mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 13:52:51 +00:00
docs: add searchable API error reference (#12502)
## Summary - Add a searchable catalog of every error ID ZITADEL's gRPC/Connect APIs can return (`content/apis/errors.mdx`), wired into the sidebar next to "gRPC Status Codes" (with a cross-link added there too). There was previously no such reference — error IDs are assigned ad hoc at ~3,800 call sites across the backend. - `scripts/generate-error-reference.ts` scans `internal/**/*.go` and `backend/**/*.go` for `zerrors.Throw*()` call sites, resolves i18n messages, and clusters ~3,200 distinct IDs into ~1,160 distinct causes by (subsystem, gRPC code, message) — so identical causes are merged into one entry instead of repeated ~3,200 times. - Detects real ID collisions (same ID thrown for genuinely different reasons at different call sites) and surfaces them as warnings, rather than silently merging them. - Generates a worked example API response for every cause. - 116 of the highest-impact causes (covering the majority of call sites) carry an explanation written against the actual source rather than the raw message text; the rest carry a mechanically derived explanation — both are visibly labeled by source so the depth of research is transparent. - New `ErrorReference` component renders the catalog as a searchable, collapsible subsystem → gRPC code → cause tree. The generator is a standalone script (`pnpm generate:error-reference` in `apps/docs`), not wired into the docs build's `generate` chain, since scanning the whole Go backend on every docs build would be wasteful. The generated `data.json` and the curated overrides are committed, the same way `content/apis/benchmarks/**/output.json` is already committed despite being externally generated. ## Test plan - [x] `pnpm nx run @zitadel/docs:check-types` passes - [x] `pnpm nx run @zitadel/docs:lint` passes - [x] `pnpm nx run @zitadel/docs:check-links` passes - [x] Verified locally in `pnpm nx run @zitadel/docs:dev`: page renders, tree expands/collapses, search filters by ID/message, collision warnings render correctly (e.g. `AUTHZ-Kl3p0`) --------- Co-authored-by: Rajat Singh <[email protected]> Co-authored-by: Claude Sonnet 5 <[email protected]> Co-authored-by: Marco A. <[email protected]>
This commit is contained in:
co-authored by
Rajat Singh
Claude Sonnet 5
Marco A.
parent
8b87ca50d4
commit
e8d95f306b
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"command|INVALID_ARGUMENT|Errors.Invalid.Argument": { "why": "A shared low-level validation check failed somewhere in the request — a required field was left empty, malformed, or out of range. The exact wording is reused verbatim by dozens of unrelated checks across the command layer (most often identity-provider configuration fields, domain names, and settings values), so the field at fault depends on the specific error ID's call site, not the message text." },
|
||||
"command|INVALID_ARGUMENT|ID missing": { "why": "A required ID field on the request was left empty. The check is shared across dozens of unrelated resource types (schemas, SMTP/SMS configs, actions, applications, and more), so which ID is missing depends on the specific call site, not the message text." },
|
||||
"command|INVALID_ARGUMENT|Resource Owner Organisation missing": { "why": "The request omitted the organization ID (resourceOwner) that the target resource belongs to — every one of these commands needs an org ID to know which event stream to operate on." },
|
||||
"command|INVALID_ARGUMENT|User ID missing": { "why": "The target user's ID was left empty on a user-scoped command such as deactivate, lock, reactivate, remove, or sign-out — ZITADEL needs a concrete user ID to know which account to act on." },
|
||||
"command|NOT_FOUND|Identity Provider Configuration doesn't exist": { "why": "The instance-level identity provider (LDAP, SAML, generic OIDC, or a Zitadel provider) referenced by ID for an update or certificate-regeneration request doesn't exist — it was never created, or has already been removed." },
|
||||
"command|NOT_FOUND|User could not be found": { "why": "The user ID passed to the command doesn't correspond to an existing user — it was never created, or the account has already been deleted." },
|
||||
"command|FAILED_PRECONDITION|User could not be found": { "why": "Phone commands (add, verify, resend a code, remove) resolve the owning user first — the user's write model shows the account doesn't exist or was already removed, leaving no user to attach the phone number to." },
|
||||
"command|NOT_FOUND|Private Label Policy not found": { "why": "The organization hasn't configured a custom branding/label policy yet, so a request to change it or manage its logo/icon assets has no existing policy to act on." },
|
||||
"command|INTERNAL|An internal error occurred": { "why": "Building or pushing the underlying event(s) for the request failed unexpectedly — e.g. an eventstore write failure — rather than anything being wrong with the request's contents. This points to a server-side/infra issue rather than a fixable input." },
|
||||
"command|NOT_FOUND|Default Private Label Policy not found": { "why": "The instance-wide default branding/label policy hasn't been set up yet, so a request to change it or add a default logo/icon/font has nothing to operate on." },
|
||||
"command|INTERNAL|Object not created": { "why": "Uploading a label-policy asset (logo or icon) to the configured object storage backend failed, so the file was never persisted." },
|
||||
"command|FAILED_PRECONDITION|No changes": { "why": "The update request's values are identical to what's already stored, so there's nothing new to persist. This guard is shared by many 'change X' commands — OIDC/SAML app config, application name, OIDC settings — whenever the computed diff is empty." },
|
||||
"command|NOT_FOUND|SMTP configuration not found": { "why": "The SMTP configuration referenced by its (resourceOwner, id) pair doesn't exist — wrong ID, wrong org, or it was already removed — so it can't be changed, activated, or deleted." },
|
||||
"command|FAILED_PRECONDITION|Multifactor OTP (OneTimePassword) isn't ready": { "why": "An OTP check (TOTP, or OTP via SMS/email) was attempted before the user finished setting up that factor — its state isn't 'ready' yet, so there's no verified secret to check the submitted code against." },
|
||||
"command|INVALID_ARGUMENT|Application invalid": { "why": "The application payload failed basic validation — a required field like the app name is empty, or a type-specific requirement for the OIDC/SAML/API configuration wasn't met." },
|
||||
"command|INVALID_ARGUMENT|Code is invalid": { "why": "The submitted verification code — an init code, or a passwordless/passkey registration code — doesn't match what was generated and stored for this user, or it has expired." },
|
||||
"command|INVALID_ARGUMENT|Multifactor invalid": { "why": "The second-factor or multi-factor type passed when adding or removing a factor from a login policy isn't a recognized value — e.g. it was left unspecified." },
|
||||
"command|FAILED_PRECONDITION|Identity Provider Configuration doesn't exist": { "why": "The identity provider ID referenced when starting a login/linking intent, or when adding an IDP link to a user, doesn't correspond to any IDP configured on the org or instance." },
|
||||
"command|FAILED_PRECONDITION|User is locked": { "why": "The user's account is currently locked — typically from too many failed verification attempts — so further recovery-code checks or removal are rejected until it's unlocked." },
|
||||
"command|NOT_FOUND|Project not found": { "why": "The project ID doesn't resolve to an existing project under the given organization — never created, wrong org, or already removed." },
|
||||
"command|INVALID_ARGUMENT|Metadata is invalid": { "why": "A metadata key in the request is empty or otherwise fails validation when setting or bulk-removing metadata on a user or organization." },
|
||||
"command|INVALID_ARGUMENT|SAML Metadata format error": { "why": "The SAML metadata XML — supplied directly or fetched from the metadata URL — couldn't be parsed as valid SAML metadata for the identity provider." },
|
||||
"command|INVALID_ARGUMENT|SAML metadata is missing": { "why": "A metadata URL was given for a SAML identity provider, but fetching the XML from that URL failed, so no metadata was available to configure the provider despite the name." },
|
||||
"command|FAILED_PRECONDITION|Organisation not found": { "why": "The organization ID referenced by the command — as the target org, the granted org on a user grant, or the org a group is being created in — doesn't exist." },
|
||||
"command|FAILED_PRECONDITION|User ID missing": { "why": "An internal session or MFA-setup helper needed the session's associated user ID, but it was empty — the session hasn't been linked to a user yet." },
|
||||
"command|FAILED_PRECONDITION|User is not yet initialized": { "why": "The target user is still in the 'initial' state — they haven't completed their invite/first-login flow — so actions that assume an active account, like requesting a password reset or verifying an email, are rejected until then." },
|
||||
"command|NOT_FOUND|Application doesn't exist": { "why": "The application referenced by project ID + app ID doesn't exist — never created or already removed — so it can't be renamed, have its secret regenerated, or be deleted." },
|
||||
"command|NOT_FOUND|Errors.NotFound": { "why": "A referenced resource couldn't be located — depending on the call site, the object a permission check needed an owning org for, an organization-settings record, or an instance membership." },
|
||||
"command|NOT_FOUND|SMS configuration not found": { "why": "The SMS provider configuration referenced by (resourceOwner, id) doesn't exist, or exists but isn't the provider type — Twilio vs. generic HTTP — the command expected." },
|
||||
"command|INVALID_ARGUMENT|Execution is invalid": { "why": "An action-v2 execution condition must set exactly one of its mutually exclusive selectors (method/service/'all', or event/group/'all') — none, or more than one, was set." },
|
||||
"command|INVALID_ARGUMENT|Project member is invalid": { "why": "The project ID, target user ID, or role list is missing, or one of the given roles isn't a valid project role, when adding, changing, or removing a project member." },
|
||||
"command|FAILED_PRECONDITION|Code not found": { "why": "A code check (email, phone, or OTP) was attempted before a code was ever requested for this user — no code is on record, or the configured code provider is missing." },
|
||||
"command|FAILED_PRECONDITION|Refresh Token is invalid": { "why": "During an OIDC token refresh, the presented refresh token doesn't match a currently active session, has passed its absolute or idle expiration, or doesn't parse into ZITADEL's expected <sessionID>:<tokenID> format." },
|
||||
"command|NOT_FOUND|Code not found": { "why": "There's no pending verification code for this user — verifying an email code, resending an init code, or sending a passwordless-init code was requested with no outstanding code on record." },
|
||||
"command|NOT_FOUND|Execution condition is invalid": { "why": "An action-v2 execution's condition references an event name, event group, or function identifier that doesn't exist in ZITADEL's registry of executable conditions." },
|
||||
"command|INVALID_ARGUMENT|ClientID missing": { "why": "The Apple identity provider's Services ID (client ID) field was left empty when adding or updating an Apple IDP configuration." },
|
||||
"command|INVALID_ARGUMENT|Code is empty": { "why": "A verification code (phone, email, or OTP) was submitted as an empty string when trying to verify it." },
|
||||
"command|INVALID_ARGUMENT|Errors.Project.Grant.Member.Invalid": { "why": "The project ID, user ID, role list, or org/grant ID is missing when adding or changing a project grant member, or one of the given roles isn't a valid project-grant role." },
|
||||
"command|INVALID_ARGUMENT|Id missing": { "why": "A user grant ID — or one of the IDs in a bulk-remove list — was left empty when deactivating or removing a grant." },
|
||||
"command|INVALID_ARGUMENT|Invalid Private Key format": { "why": "The private key bytes supplied for an Apple identity provider couldn't be parsed as a valid key — the content is malformed or corrupted." },
|
||||
"command|INVALID_ARGUMENT|KeyID missing": { "why": "The Apple identity provider's Key ID field, which identifies which private key signs the client secret, was left empty when adding or updating an Apple IDP configuration." },
|
||||
"command|INVALID_ARGUMENT|Password is empty": { "why": "A password value was left empty when setting, changing, or checking a user's password — or, for a hash-based set, neither a plaintext password nor an encoded hash was given." },
|
||||
"command|INVALID_ARGUMENT|TeamID missing": { "why": "The Apple identity provider's Developer Team ID field was left empty when adding or updating an Apple IDP configuration." },
|
||||
"command|FAILED_PRECONDITION|Code is empty": { "why": "A resend-code request — phone or email, on either the schema-user or human-user model — was made, but no code has ever been generated for this user; there's nothing to resend until an initial code is created." },
|
||||
"command|FAILED_PRECONDITION|Errors.Org.DomainPolicy.NotExisting": { "why": "Loading the org's domain/username policy (falling back to the instance default) failed while validating a username change or user removal — this wraps whatever underlying lookup error occurred, rather than pointing at one specific missing setting." },
|
||||
"command|FAILED_PRECONDITION|Errors.User.AlreadyExisting": { "why": "The user ID supplied — or auto-generated — when creating a human or machine user already belongs to an existing user account." },
|
||||
"command|FAILED_PRECONDITION|ID missing": { "why": "An internal WebAuthn/passkey helper — registering or verifying a credential, or sending a passwordless init code — needed the user ID, and sometimes a credential ID, but received an empty value." },
|
||||
"command|FAILED_PRECONDITION|Project Grant is invalid": { "why": "The project grant's resource owner doesn't match the actual owning org of the project, or the grant is being created for the project's own organization — an org mismatch on the grant." },
|
||||
"command|FAILED_PRECONDITION|Project not found": { "why": "The project ID doesn't resolve to an active project for the given org. This is the same underlying condition as the NOT_FOUND variant, surfacing here because the project is checked as a precondition of another command rather than as its direct target." },
|
||||
"command|FAILED_PRECONDITION|Role is invalid": { "why": "A project role's resource owner doesn't match the resource owner of the project it's being added to or changed on — the role and its parent project disagree about which org owns them." },
|
||||
"command|FAILED_PRECONDITION|Token is invalid": { "why": "An OIDC access token being checked against a session doesn't match the session's current token, the session isn't active, or the token has already expired." },
|
||||
"command|NOT_FOUND|Action not found": { "why": "The (deprecated v1) action ID referenced doesn't exist for the given organization — never created, or already removed." },
|
||||
"command|NOT_FOUND|Device Authorization Request does not exist": { "why": "The device code presented when approving or canceling an OAuth device-authorization flow doesn't match any pending request — a wrong, expired, or already-completed device code." },
|
||||
"command|NOT_FOUND|Errors.Instance.DebugNotificationProvider.NotFound": { "why": "The instance's debug notification provider — a test sink that logs or writes notifications to a file instead of sending them — hasn't been configured, so there's nothing to change or remove." },
|
||||
"command|NOT_FOUND|Login Policy not found": { "why": "The organization hasn't configured its own login policy, so a request to modify it — adding an IDP, removing the policy — has no existing policy to act on." },
|
||||
"command|NOT_FOUND|Multifactor not existing": { "why": "The second-factor or multi-factor method being removed from a login policy (instance-wide default or org-level) was never added, or has already been removed." },
|
||||
"command|NOT_FOUND|Multifactor OTP (OneTimePassword) doesn't exist": { "why": "The user never set up a TOTP or OTP-via-email second factor, or already removed it, so there's nothing to verify or delete." },
|
||||
"command|NOT_FOUND|Organisation not found": { "why": "The organization ID doesn't correspond to an existing org — never created, or already removed — when trying to rename, reactivate, or delete it." },
|
||||
"command|NOT_FOUND|Phone not found": { "why": "The target user has no phone number on file to verify, resend a code for, or remove. One v2 phone-event code path reuses this same message when the user account itself no longer exists, so it isn't always literally about the phone." },
|
||||
"command|INTERNAL|unable to unmarshal application": { "why": "An application lifecycle event (changed or deactivated) stored in the eventstore couldn't be deserialized back into its expected Go struct while replaying event history — a sign of corrupted event data or an incompatible struct change, not a bad request." },
|
||||
"command|INTERNAL|unable to unmarshal label policy": { "why": "Despite the message text, this comes from the project-grant-member event mapper (changed/removed events), not label-policy code — the stored event payload couldn't be deserialized while replaying history from the eventstore." },
|
||||
"command|INTERNAL|unable to unmarshal project grant": { "why": "A project-grant lifecycle event (removed, or cascade-changed) stored in the eventstore couldn't be deserialized back into its expected Go struct while replaying event history." }
|
||||
}
|
||||
Reference in New Issue
Block a user