API Errors¶
The API returns errors in GraphQL’s errors array. When using HTTP, the response status code matches the error type. Each error has a message string. The backend uses NestJS HTTP exceptions, so clients can rely on status codes and message text for handling.
400 Bad Request¶
Validation failed or invalid input.
| Message | When |
|---|---|
| Validation failed. (or constraint messages from class-validator) | createRequest or createComment input fails validation (e.g. max length, invalid UUID) |
| Invalid role. Must be one of: admin, member. | addTeamMember or addProjectMember with invalid role |
| Unable to create team. Please try again. | createTeam failed |
| Unable to create project. Please try again. | createProject failed |
| Unable to create request. Please try again. | createRequest failed |
| Unable to create comment. Please try again. | createComment failed |
| Unable to create attachment. Please try again. | createAttachment failed |
| Unable to create tag. Please try again. | createTag failed |
| Unable to create status. Please try again. | createStatus failed |
| Unable to add project member. Please try again. | addProjectMember failed |
| Unable to add team member. Please try again. | addTeamMember failed |
| Unable to add tag to request. Please try again. | addRequestTag failed |
| Selected plan is not available. | Billing checkout or workspace signup with invalid/archived/disabled plan |
| Selected plan does not have a Stripe price configured for this billing cadence. | createSignupCheckoutSession in Stripe mode without matching plan price id |
| Checkout must be completed before creating a workspace. | completeWorkspaceSignup with stubCheckoutAck: false |
| Checkout has not completed yet. Refresh after payment finishes. | finalizeSignupCheckout before the provider marks the session paid |
| Stripe webhook delivery is not enabled on this deployment. | POST /webhooks/stripe when BILLING_PROVIDER is not stripe |
| Missing raw request body. Stripe webhook signature cannot be verified. | Webhook request without raw body middleware |
| Webhook delivery is not supported in stub billing mode. | Internal stub provider (should not reach clients) |
401 Unauthorized¶
Missing or invalid authentication.
| Message | When |
|---|---|
| Authentication required. Provide a valid Bearer token in the Authorization header. | GraphQL operation requires auth but no valid token was sent |
| You must be signed in to perform this action. | Authenticated operation called without a token (e.g. mutations, team/project member queries) |
| You must be signed in to submit a request to a private project. | createRequest for a private project without a token |
| You must be signed in to start checkout. | createSignupCheckoutSession without a token |
| You must be signed in to complete checkout. | finalizeSignupCheckout without a token |
| This checkout session belongs to a different user. | finalizeSignupCheckout when session userId does not match the caller |
| Token expired. Please sign in again. | JWT verification: token expired |
| Invalid token. Please sign in again. | JWT verification: invalid signature or algorithm |
| Authentication failed: missing user identifier. | JWT payload missing sub claim |
| Authentication failed: … | Other JWT verification failures (e.g. token-invalid, token-invalid-signature) |
403 Forbidden¶
Permission denied; the resource may exist but the user is not allowed to access or modify it.
| Message | When |
|---|---|
| Project not found. | requireProjectReadAccess, requireProjectMember, or requireProjectAdmin: project ID not found or no access |
| You are not a member of this team. | Operation requires team membership (e.g. projects list, createProject) |
| Team admin access is required. | addTeamMember, removeTeamMember, or team-admin-only action |
| You are not a member of this project. | requireProjectMember: user is not a project member or team member |
| Project or team admin access is required. | requireProjectAdmin: user is not project or team admin |
| You must be a project member or team admin. | requireProjectMemberOrTeamAdmin: read/action on private project without membership or team admin |
| You must be signed in to view this project. | Reading a private project without a token |
| Request not found. | Request edit/delete/status/lock permission check: request ID not found or no access |
| You are not authorized to update this request. | updateRequest: user is not owner, project admin, or team admin |
| You are not authorized to delete this request. | deleteRequest: user is not owner, project admin, or team admin |
| This request is locked and cannot be edited. | updateRequest by the request owner while isLocked = true. Project/team admins and super admins are exempt. |
| This request is locked and cannot be deleted. | deleteRequest by the request owner while isLocked = true. Project/team admins and super admins are exempt. |
| Only project or team admins can change the request status. | setRequestStatus, or updateRequest with statusId, called by a non-admin (including the request owner). |
| Only project or team admins can lock or unlock a request. | lockRequest called by a non-admin (including the request owner). |
| Comment not found. | canEditComment or canHideOrDeleteComment: comment not found or no access |
| Project or team admin access is required to hide or delete this comment. | setCommentHidden or deleteComment: user is not project or team admin |
| You are not authorized to edit this comment. | updateComment: user is not comment author, project admin, or team admin |
| Attachment not found. | canDeleteAttachment: attachment not found or no access |
| You are not authorized to delete this attachment. | deleteAttachment: user is not attachment owner, project admin, or team admin |
| Plan limit reached: this workspace allows up to N project(s). Upgrade the plan or contact support. | createProject when the team's effective maxProjects limit would be exceeded. Super admins bypass. (SFR-31) |
| Plan limit reached: this workspace allows up to N team member(s). Upgrade the plan or contact support. | addTeamMember or inviteTeamMember when the team's effective maxTeamMembers limit would be exceeded. Super admins bypass. (SFR-31) |
| Super admin access required. | setTeamPlanOverrides called by a non-super-admin caller |
Invalid plan override for <key>: must be a non-negative integer or null. |
setTeamPlanOverrides with a malformed numeric override |
404 Not Found¶
Resource missing when the resolver throws NotFoundException (e.g. invalid ID for a create or mutation).
| Message | When |
|---|---|
| Request not found. | createComment, createAttachment, addVote, removeVote with non-existent requestId |
| Project not found. | createRequest with non-existent projectId (or project lookup before create) |
| Checkout session not found. | finalizeSignupCheckout with unknown checkoutSessionId |
| User not found. | Workspace signup when the authenticated user row is missing |
| Team not found. | teamPlanUsage or setTeamPlanOverrides with an unknown teamId |
503 Service Unavailable¶
Temporary server or upstream failure.
| Message | When |
|---|---|
| Unable to load your profile from the authentication provider. Please try again. | Clerk profile fetch failed during auth (e.g. first sign-in when user record is missing email/name) |