Area
services/platform/convex/team_members/mutations.ts — addMember and removeMember mutations (both client-callable via mutation()).
Steps to reproduce
- Attempt to add a team member as a non-admin → toast appears but console logs uncaught Convex Server Error.
- Attempt to add a user who is already a team member → same opaque Server Error in console.
- Attempt to remove the last member from a team → rejection toast + console Server Error.
- Any unauthenticated call to either mutation → raw
Error('Unauthenticated') instead of a typed code.
Expected
All business-logic rejections (auth, RBAC, not-found, duplicate-member, last-member guard) throw ConvexError({ code: '...' }) so the client can:
- distinguish error types without string-matching
- handle errors without triggering an uncaught Server Error in the console
Actual
Every rejection in both mutations uses throw new Error(...). Convex surfaces plain Error as an opaque "Server Error" to the client; only ConvexError is transmitted transparently.
Evidence
services/platform/convex/team_members/mutations.ts:23 — throw new Error('Unauthenticated') (addMember)
services/platform/convex/team_members/mutations.ts:33 — throw new Error('Only admins can add team members') (addMember)
services/platform/convex/team_members/mutations.ts:41 — throw new Error('Team not found in this organization') (addMember)
services/platform/convex/team_members/mutations.ts:60 — throw new Error('User is not a member of this organization') (addMember)
services/platform/convex/team_members/mutations.ts:75 — throw new Error('User is already a member of this team') (addMember)
services/platform/convex/team_members/mutations.ts:119 — throw new Error('Unauthenticated') (removeMember)
services/platform/convex/team_members/mutations.ts:137 — throw new Error('Team member not found') (removeMember)
services/platform/convex/team_members/mutations.ts:142 — throw new Error('Only admins can remove other team members') (removeMember)
services/platform/convex/team_members/mutations.ts:152 — throw new Error('Team not found in this organization') (removeMember)
services/platform/convex/team_members/mutations.ts:165 — throw new Error('Cannot remove the last team member. Delete the team instead.') (removeMember)
Notes
The fix pattern is established in services/platform/convex/tasks/mutations.ts (imports ConvexError from 'convex/values', throws new ConvexError({ code: 'UNAUTHENTICATED' }) etc.). Apply the same to both mutations; suggested codes: UNAUTHENTICATED, RBAC_FORBIDDEN, TEAM_NOT_FOUND, USER_NOT_ORG_MEMBER, TEAM_MEMBER_ALREADY_EXISTS, TEAM_MEMBER_NOT_FOUND, TEAM_LAST_MEMBER.
Area
services/platform/convex/team_members/mutations.ts—addMemberandremoveMembermutations (both client-callable viamutation()).Steps to reproduce
Error('Unauthenticated')instead of a typed code.Expected
All business-logic rejections (auth, RBAC, not-found, duplicate-member, last-member guard) throw
ConvexError({ code: '...' })so the client can:Actual
Every rejection in both mutations uses
throw new Error(...). Convex surfaces plainErroras an opaque "Server Error" to the client; onlyConvexErroris transmitted transparently.Evidence
services/platform/convex/team_members/mutations.ts:23—throw new Error('Unauthenticated')(addMember)services/platform/convex/team_members/mutations.ts:33—throw new Error('Only admins can add team members')(addMember)services/platform/convex/team_members/mutations.ts:41—throw new Error('Team not found in this organization')(addMember)services/platform/convex/team_members/mutations.ts:60—throw new Error('User is not a member of this organization')(addMember)services/platform/convex/team_members/mutations.ts:75—throw new Error('User is already a member of this team')(addMember)services/platform/convex/team_members/mutations.ts:119—throw new Error('Unauthenticated')(removeMember)services/platform/convex/team_members/mutations.ts:137—throw new Error('Team member not found')(removeMember)services/platform/convex/team_members/mutations.ts:142—throw new Error('Only admins can remove other team members')(removeMember)services/platform/convex/team_members/mutations.ts:152—throw new Error('Team not found in this organization')(removeMember)services/platform/convex/team_members/mutations.ts:165—throw new Error('Cannot remove the last team member. Delete the team instead.')(removeMember)Notes
The fix pattern is established in
services/platform/convex/tasks/mutations.ts(importsConvexErrorfrom'convex/values', throwsnew ConvexError({ code: 'UNAUTHENTICATED' })etc.). Apply the same to both mutations; suggested codes:UNAUTHENTICATED,RBAC_FORBIDDEN,TEAM_NOT_FOUND,USER_NOT_ORG_MEMBER,TEAM_MEMBER_ALREADY_EXISTS,TEAM_MEMBER_NOT_FOUND,TEAM_LAST_MEMBER.