Appearance
Error codes
Every error is an RFC 9457 Problem Details document with a stable code:
json
{
"type": "https://docs.anchorkeel.io/errors/sources.blocked-host",
"title": "…",
"status": 422,
"detail": "That address is on a private or internal network. …",
"code": "Sources.BlockedHost",
"traceId": "00-…",
"errors": { "host": ["…"] }
}- Branch on
code, never ondetail(wording can change). - Validation failures (400) list field errors in
errors. Unknown metric or dimension names (422) addnameandsuggestions. Unmet certification criteria (422) adddetails. - HTTP status by error type: Validation 400, Unauthorized 401, Forbidden 403, NotFound 404, Conflict 409, Concurrency (stale
If-Match/ expected version) 412, Unprocessable (a domain rule) 422, RateLimited 429, Failure 500. - Cross-tenant access looks exactly like "not found" (404): another tenant's resources are never disclosed.
- Provider (database, Git, LLM) error text is never passed through; Keel writes its own message.
All codes
Generated from the code. … marks a value filled in at run time.
482 codes in 28 areas.
Agents
| Code | HTTP | Message |
|---|---|---|
Agents.CertificateInvalid | 400 | The agent certificate must be one PEM-encoded ECDSA P-256 certificate without its private key. |
Agents.ChannelInvalid | 400 | The release channel must be stable, beta or pinned (or empty to follow the pool). |
Agents.EnrollmentTokenInvalid | 401 | The enrollment token is invalid, expired or already used. Create a new agent enrollment. |
Agents.LocationInvalid | 400 | The location must be at most 80 characters. |
Agents.NameInvalid | 400 | The agent name must be 1–80 characters. |
Agents.NameTaken | 409 | An agent with this name already exists in the workspace. |
Agents.NotFound | 404 | The private agent was not found. |
Agents.PinnedVersionInvalid | 400 | A pinned channel needs a version such as 1.4.0 (and only a pinned channel takes one). |
Agents.PoolInvalid | 400 | The pool name must be 1–40 lower-case letters, digits, '.', '_' or '-'. |
Agents.ReleaseNotFound | 404 | The control plane has no agent package of this version for this platform. |
Agents.ReleaseUnsupported | 422 | Agent … is two or more major versions behind the control plane (…) and would be refused: pin a newer version. |
Agents.Revoked | 403 | This agent was revoked. |
Agents.VersionUnsupported | 422 | Keel agent … is two or more major versions behind the control plane (…) and was refused. Update it: … |
Agents.WorkNotFound | 404 | The work item does not exist, is not assigned to this agent, or the server stopped waiting for it. |
Audit
| Code | HTTP | Message |
|---|---|---|
Audit.InvalidCursor | 400 | The cursor is not valid. |
Audit.InvalidDateRange | 400 | 'from' must be before 'to'. |
Audit.RetentionFailed | 500 | Retention crashed for at least one tenant. |
Audit.RetentionOutOfRange | 400 | Retention must be between … and … days. |
Audit.UnknownExportFormat | 400 | Export format must be csv or json. |
Audit.VerificationFailed | 500 | Verification crashed for at least one tenant. |
Authorization
| Code | HTTP | Message |
|---|---|---|
Authorization.Forbidden | 403 | You do not have permission to approve change requests. |
Billing
| Code | HTTP | Message |
|---|---|---|
Billing.AnnualValueInvalid | 400 | The contract's annual value is an amount in US dollars of 0 or more, with at most two decimals. |
Billing.CheckoutRequired | 422 | Choose a paid plan first; add-ons are added to a paid subscription. |
Billing.ContactSales | 422 | This plan is sold by contract. Talk to sales to switch to it. |
Billing.LimitOverrideInvalid | 400 | A contract limit names a known limit and is a whole number of 0 or more, or unlimited. |
Billing.ManagedByContract | 422 | The subscription is managed by contract. Contact Anchor to change it. |
Billing.NoSubscription | 404 | The tenant has no subscription yet. |
Billing.NotTrialing | 409 | The subscription is not a Keel trial. |
Billing.PaymentProviderFailed | 500 | The payment provider did not answer. Try again in a moment. |
Billing.PaymentsDisabled | 422 | Payments are not configured on this deployment. |
Billing.ReadOnly | 403 | This workspace is read-only because its trial or subscription has ended. Choose a plan in Settings → Billing to make changes again; nothing has been deleted. |
Billing.SamePlan | 409 | The tenant is already on this plan. |
Billing.TrialExpiryFailed | 500 | Expiring trials failed for at least one tenant. |
Billing.TrialExtensionClosed | 409 | The trial ended more than 30 days ago and can no longer be extended. Put the tenant on a plan or a contract instead. |
Billing.TrialExtensionInvalid | 400 | A trial is extended by 1 to 90 days. |
Billing.TrialNotExpired | 409 | The trial has not ended. |
Billing.TrialTooLong | 422 | A trial lasts at most 90 days from its start, extensions included. |
Billing.UnknownAddOn | 400 | The catalog has no such add-on. |
Billing.UnknownPlan | 400 | The catalog has no such plan. |
Billing.WebhookPayloadInvalid | 400 | The webhook payload is not a valid event. |
Billing.WebhookSignatureInvalid | 401 | The webhook signature is missing, invalid or too old. |
Cutover
| Code | HTTP | Message |
|---|---|---|
Cutover.AlreadyRolledBack | 409 | The cutover switch is already rolled back. |
Cutover.AlreadySwitched | 409 | The cutover switch is already applied. |
Cutover.CertifiedMetricUnmappable | 422 | Certified metric(s) … read columns the migration plan drops or transforms into something else. |
Cutover.Forbidden | 403 | Only a Steward or Owner running the Migrate cutover can switch or roll back serving. |
Cutover.InvalidMap | 400 | '…' is not a schema-qualified table (schema.table) or column (schema.table.column). |
Cutover.InvalidModel | 422 | Model … would not be valid on the target: … |
Cutover.Pending | 409 | The cutover switch did not finish: confirm the switch again to complete it before rolling back. |
Cutover.SameSource | 400 | The migration's source and target are the same data source. |
Cutover.SourceNotFound | 404 | The migration's source is not a data source of this workspace. |
Cutover.SwitchNotFound | 404 | The cutover switch was not found. |
Cutover.TargetNotFound | 404 | The migration's target is not a data source of this workspace. |
Discovery
| Code | HTTP | Message |
|---|---|---|
Discovery.BusinessNameRequired | 400 | A business name is required. |
Discovery.ColumnsNotFound | 400 | The tables or columns of the relationship do not exist in the latest snapshot. |
Discovery.DriftEventNotFound | 404 | The drift event was not found. |
Discovery.DriftEventResolved | 422 | The drift event is already resolved. |
Discovery.DriftNoteTooLong | 400 | The note can be at most … characters. |
Discovery.NoBaseline | 422 | Scan the source once before checking it for drift: drift is measured against the last snapshot. |
Discovery.NoSnapshot | 422 | Scan the source before asserting relationships. |
Discovery.ProposalNotDecided | 422 | Only accepted or rejected proposals can be undone. |
Discovery.ProposalNotFound | 404 | The proposal was not found. |
Discovery.ProposalSuperseded | 422 | The latest scan no longer supports this proposal. |
Discovery.RunFinished | 422 | The run has already finished. |
Discovery.RunInProgress | 409 | A scan of this source is already running. Wait for it to finish or cancel it. |
Discovery.RunNotFound | 404 | The discovery run was not found. |
Discovery.RunNotRetryable | 422 | Only failed or cancelled runs can be retried. |
Discovery.RunNotRunnable | 422 | The run cannot be started in its current state. |
Discovery.RunNotVisible | 500 | The run is not committed yet. |
Discovery.SnapshotNotFound | 404 | The snapshot was not found. |
Discovery.SourceNotFound | 404 | The data source was not found. |
Discovery.TableNotFound | 404 | The table was not found. |
Governance
| Code | HTTP | Message |
|---|---|---|
Governance.AlreadyLinked | 409 | The term is already linked to this asset. |
Governance.ApprovedTermNeedsSteward | 403 | Approved terms can only be changed by stewards and admins. |
Governance.CertificationDeprecated | 422 | The metric is deprecated. |
Governance.CertificationExpiryFailed | 500 | Certification expiry failed for at least one tenant. |
Governance.DomainNameTaken | 409 | A domain with this name already exists under the same parent. |
Governance.DomainNotFound | 404 | The domain was not found. |
Governance.DomainTooDeep | 422 | Domains nest at most 5 levels deep. |
Governance.EmptySelection | 400 | Choose a domain, or a source and schema, to assign in bulk. |
Governance.InvalidAssetRef | 400 | Asset references look like model:{id}/entity:{name}, metric:{id}/{name}, source:{id}/table:{schema.table} (see docs/02 §6). |
Governance.InvalidCertificationRules | 400 | The minimum trust score is 0–100 and the validity 30–730 days. |
Governance.InvalidDbtManifest | 400 | The body is not a dbt manifest.json (metadata and nodes are required). |
Governance.InvalidDefinition | 400 | A definition is at most 20,000 characters. |
Governance.InvalidDomainName | 400 | A domain name is 1–80 characters and has no '›'. |
Governance.InvalidImport | 400 | The file could not be read as a glossary (see the expected columns). |
Governance.InvalidLineageDepth | 400 | Depth is between 1 and 10. |
Governance.InvalidLineageDirection | 400 | Direction is up, down or both. |
Governance.InvalidMask | 400 | A column mask is Full, Hash, Null, or Partial with 1–8 visible trailing characters. |
Governance.InvalidOpenLineageEvent | 400 | The body is not an OpenLineage RunEvent (job.namespace, job.name, inputs and outputs are required). |
Governance.InvalidPerson | 400 | Owners and stewards must be members of the workspace. |
Governance.InvalidPolicyDescription | 400 | A description is at most 2,000 characters. |
Governance.InvalidPolicyName | 400 | A policy name is 1–120 letters, digits, '_', '.' or '-', starting with a letter or digit. |
Governance.InvalidPolicyRoles | 400 | Roles are Owner, Admin, Steward, Modeler, Analyst or Viewer, and a role cannot be both targeted and exempt. |
Governance.InvalidPolicyScope | 400 | The scope is an asset (masks: entity, dimension, table or column; row filters: entity or table), a tag, a domain, or a sensitivity level. |
Governance.InvalidRelated | 400 | A term has at most 20 related terms of the same workspace. |
Governance.InvalidReplacement | 422 | The replacement must be another term of the workspace that is not deprecated. |
Governance.InvalidRowFilter | 400 | A row filter names a dimension, an operator (eq, ne, in, not_in, gt, gte, lt, lte, is_null, is_not_null) and its values. |
Governance.InvalidSynonym | 400 | Synonyms are 1–120 characters, at most 30 per term, and differ from the term's name. |
Governance.InvalidTemplate | 400 | Templates are {{user.attributes.name}}, {{user.id}} or {{user.roles}} ({{user.roles}} only as a whole value with eq, ne, in or not_in). |
Governance.InvalidTermName | 400 | A term name is 1–120 characters. |
Governance.LineageModelNotFound | 404 | The model was not found in this workspace. |
Governance.LineageNodeNotFound | 404 | The asset is not part of any model, scanned source or imported lineage of the workspace. |
Governance.LineageTooLarge | 422 | A lineage scope holds at most … edges. |
Governance.LineageWorkspaceRequired | 400 | Pass workspaceId, or call with an API key (its workspace is used). |
Governance.LinkNotFound | 404 | The term is not linked to this asset. |
Governance.MemberNotFound | 404 | The user is not a member of this workspace. |
Governance.MetricNotFound | 404 | The metric was not found in this workspace's models. |
Governance.ModelNotFound | 404 | The model was not found in this workspace. |
Governance.NoOwner | 400 | Assign an owner, at least one steward, or a domain. |
Governance.NotAMetric | 400 | Only metrics (metric:{modelId}/{name}) are certified. |
Governance.NotCertified | 422 | The metric is not at a level this action applies to. |
Governance.NotDraft | 422 | Only draft terms can be submitted for review. |
Governance.NotInReview | 422 | Only terms in review can be approved. |
Governance.PolicyNameTaken | 409 | Another policy in this workspace already has this name. |
Governance.PolicyNotAccepted | 422 | Accept the suggested policy before enabling or disabling it. |
Governance.PolicyNotFound | 404 | The access policy was not found. |
Governance.PolicyRejected | 422 | A rejected suggestion cannot be edited; create a policy instead. |
Governance.PolicySuggestionDecided | 422 | The policy suggestion was already accepted or rejected. |
Governance.ReplacementRequired | 422 | The term is linked to certified metrics: choose a replacement term before deprecating it. |
Governance.SuggestionDecided | 422 | The suggestion was already accepted or rejected. |
Governance.SuggestionNotFound | 404 | The term suggestion was not found. |
Governance.TermDeprecated | 422 | The term is deprecated and can no longer change. |
Governance.TermNameTaken | 409 | Another term in this workspace already has this name. |
Governance.TermNotFound | 404 | The glossary term was not found. |
Governance.UnknownAsset | 422 | The asset does not exist in any model or scanned source of the workspace. |
Http
| Code | HTTP | Message |
|---|---|---|
Http.NotThroughFrontDoor | 403 | Requests must come through the service's front door. |
Http.RateLimited | 429 | Too many requests; retry later. |
Idempotency
| Code | HTTP | Message |
|---|---|---|
Idempotency.InProgress | 409 | A request with this Idempotency-Key is still being processed. |
Idempotency.KeyReused | 422 | This Idempotency-Key was already used with a different request. |
Identity
| Code | HTTP | Message |
|---|---|---|
Identity.AlreadyInTenant | 409 | You already belong to a tenant. |
Identity.AlreadyMember | 409 | That person is already a member. |
Identity.ApiKeyExpiryInPast | 400 | The expiry must be in the future. |
Identity.ApiKeyNotFound | 404 | The API key was not found. |
Identity.ApiKeyScopesRequired | 400 | Choose at least one scope. |
Identity.AttributesInvalid | 400 | At most 20 attributes; names are 1–64 letters, digits, '_' or '-' (unique ignoring case), values 1–200 characters. |
Identity.AutoAcceptThresholdInvalid | 400 | The auto-accept threshold must be between 0.5 and 1. |
Identity.ChannelDeliveryDeadLettered | 500 | The channel did not accept the message after every attempt. |
Identity.ChannelDeliveryFailed | 500 | The channel did not accept the message; retrying. |
Identity.ChannelDeliveryNotVisible | 500 | The delivery is not committed yet. |
Identity.ChannelNameInvalid | 400 | The name must be 1–80 characters. |
Identity.ChannelNameTaken | 409 | A channel with this name already exists in the workspace. |
Identity.ChannelNotFound | 404 | The notification channel was not found. |
Identity.ChannelPruneFailed | 500 | Pruning the channel delivery log failed for at least one tenant. |
Identity.ChannelSigningSecret | 422 | Only generic webhooks have a signing secret. |
Identity.ChannelUrlBlocked | 422 | The URL points to a private or internal address. Use a public https endpoint. |
Identity.ChannelUrlInvalid | 400 | Enter the full https:// URL of the incoming webhook. |
Identity.DigestFailed | 500 | Digest sending failed for at least one tenant. |
Identity.DnsUnavailable | 500 | DNS lookup failed. |
Identity.FeatureInvalid | 400 | Unknown feature. |
Identity.Forbidden | 403 | You do not have permission to perform this action. |
Identity.IdpAdminFailed | 500 | The identity provider refused or could not be reached. |
Identity.IdpAdminNotConfigured | 500 | Keel:Keycloak:Admin is not configured. |
Identity.InvitationEmailMismatch | 403 | The invitation was sent to a different email address. |
Identity.InvitationExpired | 422 | The invitation has expired. |
Identity.InvitationNotFound | 404 | The invitation was not found. |
Identity.InvitationUsed | 422 | The invitation has already been used or revoked. |
Identity.LastOwner | 422 | The last Owner of a tenant cannot be removed or demoted. |
Identity.LastWorkspace | 422 | The last active workspace cannot be archived. |
Identity.MemberNotFound | 404 | The member was not found. |
Identity.ModuleInvalid | 400 | Unknown module. |
Identity.NameInvalid | 400 | The name must be 1–80 characters. |
Identity.NotificationCursorInvalid | 400 | The cursor is not valid. |
Identity.NotificationNotFound | 404 | The notification was not found. |
Identity.NotificationsPeopleOnly | 403 | Only people have notifications, not API keys. |
Identity.NotificationTypeUnknown | 400 | Unknown notification type. |
Identity.OnboardingAnswerInvalid | 400 | Choose from the listed options. |
Identity.OnboardingFinished | 422 | Onboarding is already finished. |
Identity.OnboardingNotFound | 404 | There is no onboarding in progress. |
Identity.OnboardingStepInvalid | 400 | The step must be 1–4. |
Identity.PreferencesInvalid | 400 | Choose a theme, a time zone and a number format from the list. |
Identity.RegionInvalid | 400 | The data region must be US or EU. |
Identity.ScimAttributeMappingInvalid | 400 | At most 20 mappings; each SCIM attribute (a core attribute or 'urn:…:name') and each Keel attribute (1–64 letters, digits, '_' or '-') once. |
Identity.ScimCallerRequired | 403 | Only the tenant's SCIM client can call the provisioning API. |
Identity.ScimEmailInvalid | 400 | A work email is required (emails[primary] or an email-shaped userName). |
Identity.ScimGroupExists | 409 | A group with this displayName already exists. |
Identity.ScimGroupNameInvalid | 400 | displayName is required (up to 256 characters). |
Identity.ScimGroupNotFound | 404 | Resource not found. |
Identity.ScimInvalidFilter | 400 | Only 'attribute eq "value"' filters are supported. |
Identity.ScimNotEnabled | 404 | SCIM provisioning isn't set up. Generate a token first. |
Identity.ScimOwnerNotMappable | 400 | Groups can't grant Owner. Make people Owners in Settings › Members. |
Identity.ScimPatchInvalid | 400 | The PATCH operation isn't supported. |
Identity.ScimTooManyMembers | 400 | A group can have at most 50,000 members. |
Identity.ScimUserExists | 409 | A user with this userName already exists. |
Identity.ScimUserNameInvalid | 400 | userName is required (up to 256 characters). |
Identity.ScimUserNotFound | 404 | Resource not found. |
Identity.SessionIsCurrent | 422 | This is the session you're using. Use Sign out instead. |
Identity.SessionNotFound | 404 | That session was not found. |
Identity.SessionsUnavailable | 422 | Your sessions are managed by your identity provider. |
Identity.SignupClosed | 403 | Keel accounts are by invitation. Request a demo and we'll set up your workspace. |
Identity.SignupCompleted | 409 | This sign-up is already complete. Sign in to continue. |
Identity.SignupEmailInvalid | 400 | That email doesn't look right. |
Identity.SignupLinkExpired | 422 | This sign-up link has expired. Start again to get a new one. |
Identity.SignupLinkUsed | 422 | This sign-up link has already been used. Start again to get a new one. |
Identity.SignupNotFound | 404 | This sign-up link isn't valid. Start again to get a new one. |
Identity.SignupNotVerified | 422 | Verify your email before creating the workspace. |
Identity.SignupTurnstileFailed | 400 | We couldn't confirm you're not a robot. Please try again. |
Identity.SignupUnavailable | 500 | Sign-up isn't available right now. Please try again later. |
Identity.SignupWorkEmailRequired | 400 | Please use your work email. |
Identity.SlugInvalid | 400 | The slug must be 3–40 lowercase letters, digits or hyphens. |
Identity.SlugTaken | 409 | That slug is already in use. |
Identity.SsoBreakGlassRequired | 422 | Choose an Owner who keeps a break-glass sign-in. |
Identity.SsoClientIdInvalid | 400 | Enter the client ID your identity provider issued (up to 255 characters). |
Identity.SsoClientSecretRequired | 400 | Enter the client secret your identity provider issued. |
Identity.SsoDomainClaimed | 409 | That domain is already verified by another organisation. |
Identity.SsoDomainExists | 409 | That domain is already set up for this tenant. |
Identity.SsoDomainFreeMail | 400 | Consumer email domains can't be used for single sign-on. |
Identity.SsoDomainInvalid | 400 | Enter a domain such as example.com. |
Identity.SsoDomainNotFound | 404 | The domain was not found. |
Identity.SsoDomainNotVerified | 422 | We couldn't find the TXT record yet. DNS changes can take a few minutes; try again. |
Identity.SsoEnforced | 422 | Single sign-on is required right now. Turn that off before changing the identity provider. |
Identity.SsoIdpAliasInvalid | 400 | The identity provider alias must be 1–64 letters, digits, '.', '_' or '-'. |
Identity.SsoIdpUnavailable | 422 | The identity provider couldn't be registered. Check the URL is reachable and try again. |
Identity.SsoNotConfigured | 422 | Set up single sign-on first. |
Identity.SsoNotTested | 422 | Run a successful test sign-in with this configuration before requiring SSO. |
Identity.SsoNoVerifiedDomain | 422 | Verify at least one domain before requiring SSO. |
Identity.SsoRequired | 403 | Your organisation requires single sign-on. Sign in with your company SSO. |
Identity.SsoTestFailed | 422 | The test sign-in didn't come back through your identity provider. |
Identity.SsoTestTokenInvalid | 400 | The test sign-in token is not valid. |
Identity.SsoUrlInvalid | 400 | Enter the full https:// URL, without a query string. |
Identity.TenantNotFound | 404 | Depends on the case, for example: The tenant was not found. |
Identity.Unauthenticated | 401 | Authentication is required. |
Identity.UserNotProvisioned | 401 | Sign in again to finish setting up your account. |
Identity.WorkspaceArchived | 422 | The workspace is archived. |
Identity.WorkspaceNameTaken | 409 | A workspace with this name already exists. |
Identity.WorkspaceNotFound | 404 | The workspace was not found. |
Imports
| Code | HTTP | Message |
|---|---|---|
Imports.UploadTooLarge | 400 | The upload is too large: at most 10 MB uploaded, 20 MB unzipped, 2 MB per file and 1,000 files. |
Imports.UploadUnreadable | 400 | A zip in the upload could not be read. |
Jobs
| Code | HTTP | Message |
|---|---|---|
Jobs.NotFound | 404 | The job was not found. |
Jobs.UnknownEventType | 500 | The integration event type is not registered. |
Leads
| Code | HTTP | Message |
|---|---|---|
Leads.ConsentVersionMissing | 400 | The consent text version is required. |
Leads.EmailInvalid | 400 | That email doesn't look right. |
Leads.RequiredFieldMissing | 400 | Please complete the highlighted fields. |
Leads.TurnstileFailed | 400 | We couldn't confirm you're not a robot. Please reload the page and try again. |
Llm
| Code | HTTP | Message |
|---|---|---|
Llm.BudgetExceeded | 429 | The tenant's LLM token budget (daily guard or the plan's monthly allowance) is used up. |
Llm.Disabled | 422 | No LLM provider is configured. |
Llm.InvalidOutput | 500 | The model did not return valid structured output. |
Llm.ProviderFailed | 500 | The LLM provider did not answer. |
Llm.ProviderUnsupported | 422 | The tenant's LLM provider is not available. |
Migrate
| Code | HTTP | Message |
|---|---|---|
Migrate.AgentCannotWrite | 422 | The write credential's private agent has its migrate write plane turned off (Keel:Agent:MigrateWrite). Turn it on or register the credential on another agent. |
Migrate.AgentRequired | 422 | A Keel run needs the sources on the same private agent as the write credential (rows move inside your network). |
Migrate.ApproverRoleRequired | 403 | Only a Steward or Owner can switch serving to the target, approve a cutover step or roll back. |
Migrate.ChangeCaptureUnsupported | 400 | This change capture mode is not available for the source's engine. |
Migrate.CheckNotFailing | 409 | An exception can only be recorded for a failing or warning check. |
Migrate.CheckNotFound | 404 | The reconciliation check was not found in this run. |
Migrate.CodeGenerationNotFound | 404 | The code generation was not found. |
Migrate.CodeMapNotFound | 404 | The code map was not found. |
Migrate.ColumnMappingNotFound | 404 | The column mapping was not found. |
Migrate.CutoverNotStarted | 409 | Start the cutover first. |
Migrate.CutoverStepOutOfOrder | 409 | Complete the earlier cutover steps first. |
Migrate.ExceptionReasonInvalid | 400 | Explain the exception in 10 to 1000 characters. |
Migrate.ExecutorInvalid | 400 | Only workspace members whose role can run migrations (Owner, Admin or Steward) can be granted migrate:execute. |
Migrate.ForceNeedsApproval | 403 | Four-eyes is on: the second Steward or Owner forces the switch when they approve it. |
Migrate.GitUnavailable | 422 | Git delivery is not available: connect a Git repository to the workspace (Settings › Integrations). |
Migrate.InvalidRunTransition | 409 | The run is not in a state where this is possible. |
Migrate.InvalidStatusTransition | 409 | The migration is not at a stage where this is possible. |
Migrate.MappingDecided | 409 | Only a proposed mapping can be decided this way. |
Migrate.MappingRejected | 409 | A rejected mapping cannot be edited; accept it or mark it as needing work first. |
Migrate.NameInvalid | 400 | Give the migration a name of 1 to 120 characters. |
Migrate.NoTargetDatabase | 422 | Reconciliation reads the target database: set the data source that holds the target tables. |
Migrate.NotExecutor | 403 | You have not been granted migrate:execute on this migration. An Owner or Admin grants it per migration. |
Migrate.NothingAccepted | 422 | Accept at least one table mapping (with accepted columns) before committing a plan. |
Migrate.PlanAlreadyApproved | 409 | The plan version is already approved. |
Migrate.PlanNotApproved | 422 | A Steward or Owner must approve a plan version first. |
Migrate.PlanNotFound | 404 | The migration plan version was not found. |
Migrate.PlanNotLatest | 409 | Only the latest plan version can be approved. |
Migrate.PlanUnchanged | 409 | The accepted mappings are the same as the latest plan version: nothing to commit. |
Migrate.ProjectNotFound | 404 | The migration project was not found. |
Migrate.ProjectSignedOff | 409 | The migration is signed off: its mappings and plan can no longer change. |
Migrate.ReconciliationNotCompleted | 409 | The reconciliation run has not completed. |
Migrate.ReconciliationNotLatest | 409 | Only the latest completed reconciliation of the approved plan can be signed off. |
Migrate.ReconciliationRunNotFound | 404 | The reconciliation run was not found. |
Migrate.ReconciliationSignedOff | 409 | The reconciliation is already signed off. |
Migrate.ReconciliationUnsupported | 422 | Reconciliation does not run on … sources yet. |
Migrate.RecordNotVisible | 500 | The record the job works on is not committed yet. |
Migrate.ReportIntervalTooLong | 400 | The agent must report at least twice per lease (… s): choose a report interval of at most … s. |
Migrate.ReportRejected | 400 | The run report carries something other than counts, timings, lag, error codes and capped keys: it is rejected. |
Migrate.RollbackWindowClosed | 409 | The rollback window is closed. |
Migrate.RunActive | 409 | The migration already has an active run. |
Migrate.RunNotActive | 409 | The run has ended. |
Migrate.RunNotFound | 404 | The migration run was not found. |
Migrate.SameApprover | 403 | Four-eyes is on: a second Steward or Owner, not the person who requested this step, must approve it. |
Migrate.ScopeCheckInProgress | 409 | The write credential is being checked. |
Migrate.ScopeEmpty | 422 | None of the tables in the migration's scope is in the sources' latest scans: rescan the sources or widen the scope. |
Migrate.ScopeInvalid | 400 | The scope lists between 1 and 5,000 tables, each of a source of this migration (or leave it empty for every table). |
Migrate.SourceNotFound | 404 | A source of the migration was not found in this workspace. |
Migrate.SourceNotFrozen | 409 | Keel still observes changes on the source: stop the applications writing to it, then confirm again. |
Migrate.SourceNotScanned | 422 | A source of the migration has not been scanned yet: scan it before inferring mappings. |
Migrate.SourcesInvalid | 400 | Pick between 1 and 10 distinct source data sources. |
Migrate.SupervisionFailed | 500 | Supervising migration runs failed for at least one tenant. |
Migrate.TableMappingNotFound | 404 | The table mapping was not found. |
Migrate.TargetDatabaseRequired | 422 | A Keel run writes to a registered target data source: set the migration's target database. |
Migrate.TargetEmpty | 422 | The target has no tables: scan the target source, add entities to the model or upload table definitions. |
Migrate.TargetInvalid | 400 | The target is not valid: pick a data source, a semantic model or upload DDL or a dbt project. |
Migrate.TargetIsSource | 400 | The target data source cannot also be a source of the migration. |
Migrate.TargetMissing | 422 | Set the migration's target first. |
Migrate.TargetModelNotFound | 404 | The target semantic model was not found in this workspace. |
Migrate.TargetSourceNotFound | 404 | The target data source was not found in this workspace. |
Migrate.TargetUnsupported | 422 | Keel runs write to PostgreSQL, SQL Server, Snowflake and BigQuery targets: run the generated code for this target. |
Migrate.UnknownColumn | 400 | A column does not exist in the target table or in the mapping's source tables. |
Migrate.UnknownSourceTable | 400 | A source table is not in the latest scan of the migration's sources (name it schema.table). |
Migrate.UploadEmpty | 400 | Upload CREATE TABLE statements (.sql) or a dbt project (schema .yml files, or a zip of them). |
Migrate.WriteCredentialInvalid | 400 | Name the write credential's secret on the agent (letters, digits, . _ -), its user name and 1 to 50 target schemas. |
Migrate.WriteCredentialMissing | 422 | Register the project's write credential on its private agent first. |
Migrate.WriteCredentialNotAccepted | 422 | The write credential has not passed its scope check: test it and fix what the check reports. |
Migrate.WriteCredentialReused | 400 | The write credential must be a separate credential: its secret cannot be the one a source or the target reads with (ADR-0021). |
Migrate.WriteScopeRefused | 422 | The write credential can write outside the target schemas, or lacks rights the run needs: it is refused. |
Modeling
| Code | HTTP | Message |
|---|---|---|
Modeling.BranchExists | 409 | A branch with this name already exists. |
Modeling.BranchMoved | 409 | The branch moved since you loaded it. Reload and try again. |
Modeling.BranchNotFound | 404 | The branch was not found. |
Modeling.BreakingNotAcknowledged | 422 | Breaking changes affect consumers: acknowledge them before merging. |
Modeling.CannotDeleteMain | 422 | main cannot be deleted. |
Modeling.ChangeRequestClosed | 422 | The change request is no longer open. |
Modeling.ChangeRequestExists | 409 | An open change request already merges this branch. |
Modeling.ChangeRequestNotFound | 404 | The change request was not found. |
Modeling.ChecksOutdated | 409 | A branch moved since the checks ran. Re-run the checks before merging. |
Modeling.ExportNotFound | 404 | The export was not found. |
Modeling.ExportTooLarge | 422 | The export is larger than 20 MB. |
Modeling.GenerationNotVisible | 500 | The generation is not committed yet. |
Modeling.GitConnectionNotFound | 404 | No Git repository is connected to this workspace. Add one in Settings › Integrations. |
Modeling.GitDeliveryUnavailable | 422 | Git delivery is not available in this host. |
Modeling.GitProviderNotSupported | 422 | Pushing to this Git provider is not available yet: GitHub (cloud or Enterprise Server) is supported. |
Modeling.GitRepositoryUrlBlocked | 400 | The repository host is a private or internal address, which Keel does not connect to. |
Modeling.GitRepositoryUrlInvalid | 400 | Enter the repository's https URL, e.g. https://github.com/acme/analytics (no credentials in the URL). |
Modeling.GitTokenMissing | 422 | The repository's access token is missing. Enter it again in Settings › Integrations. |
Modeling.GitTokenRequired | 400 | An access token is required to connect a repository. |
Modeling.ImportBaseMissing | 422 | The model has no empty root revision to base the import branch on. |
Modeling.ImportNotFound | 404 | The import was not found. |
Modeling.InvalidApprovalCount | 400 | Required approvals is between 1 and 5. |
Modeling.InvalidBranchName | 400 | Branch names use letters, digits, - _ . and / (no leading or trailing slash). |
Modeling.InvalidDefinition | 400 | The model document is incomplete: every entity needs a name, source, keys, dimensions and measures lists. |
Modeling.InvalidExportPath | 400 | The path prefix is a relative folder of letters, digits, - _ . and / (no ".."), at most 200 characters. |
Modeling.InvalidModel | 422 | The model has validation errors. |
Modeling.InvalidModelName | 400 | A model name is 1–120 characters. |
Modeling.InvalidTitle | 400 | A title is 1–200 characters. |
Modeling.InvalidVersion | 400 | Versions look like v1.2.3 and must be higher than the latest release. |
Modeling.MainIsProtected | 403 | main is protected: open a change request, or let Owners commit directly in the model settings. |
Modeling.MergeConflicts | 409 | Both branches changed the same objects. Resolve the conflicts to merge. |
Modeling.MetricExists | 409 | The model already has a metric named …. |
Modeling.ModelNotFound | 404 | The model was not found. |
Modeling.NoImportFiles | 400 | Upload at least one model file (or a zip of the project). |
Modeling.NotApproved | 422 | The change request needs the required approvals. |
Modeling.NothingDiscovered | 422 | None of the model's sources has been scanned yet. Scan a source first. |
Modeling.NothingToMerge | 422 | The branch has no changes against its target. |
Modeling.ReleaseNotFound | 404 | The release was not found. |
Modeling.RevisionNotFound | 404 | The revision was not found. |
Modeling.SameBranch | 400 | Source and target branches must differ. |
Modeling.SelfApproval | 403 | You cannot approve your own change request. |
Modeling.ServingCutoverUnavailable | 422 | Repointing serving to the target is not available in this host. |
Modeling.StrategyActionNotFound | 404 | The strategy report has no such action. |
Modeling.UnknownExportTarget | 400 | Unknown export target. Use dbt, cube, looker, powerbi or osi. |
Modeling.UnknownImportFormat | 400 | Unknown import format. Use dbt, lookml or cube. |
Modeling.WorkingCopyNotFound | 404 | You have no working copy on this branch. |
Modeling.WorkingCopyOutdated | 409 | The branch moved since you started editing and your changes conflict with it (…). Rebase your working copy. |
Modeling.WorkingCopyStale | 412 | Your working copy was saved elsewhere (another tab?) since you loaded it. Reload it and try again. |
Modules
| Code | HTTP | Message |
|---|---|---|
Modules.NotLicensed | 404 | The module is not licensed for this tenant. |
Operations
| Code | HTTP | Message |
|---|---|---|
Operations.ConfirmationMismatch | 400 | Type the tenant's slug exactly to confirm offboarding. |
Operations.DeletionAlreadyScheduled | 409 | This organization's deletion is already scheduled. |
Operations.DeletionNotCancellable | 422 | The deletion can no longer be cancelled: it was cancelled already or its date has passed. |
Operations.DeletionNotDue | 422 | The deletion's grace period has not ended. |
Operations.DeletionNotScheduled | 404 | No deletion is scheduled for this organization. |
Operations.ImmediateReasonRequired | 400 | Deleting without the grace period needs a reason of …–… characters (the legal or abuse case). |
Operations.InvalidCursor | 400 | The page cursor is not valid. |
Operations.InvalidDateRange | 400 | The start of the range must be before its end. |
Operations.OffboardingIncomplete | 500 | Rows of the tenant remain after the purge; see the operator log. |
Operations.OffboardingPayloadInvalid | 400 | The offboarding job has no tenant. |
Operations.OperatorRequired | 403 | Only platform operators can do this. |
Operations.PlatformMemberAsCustomerOwner | 422 | A platform member can't be the first Owner of a customer tenant. Invite the customer's own Owner, or mark the tenant internal. |
Operations.PlatformOwnerRequired | 403 | Only the platform owner can do this. |
Operations.TenantNotFound | 404 | The tenant does not exist. |
Persistence
| Code | HTTP | Message |
|---|---|---|
Persistence.Concurrency | 412 | The resource was changed by someone else. Reload and try again. |
Persistence.UniqueViolation | 409 | Something with the same unique value already exists. |
Platform
| Code | HTTP | Message |
|---|---|---|
Platform.AlreadyMember | 409 | This person is already a platform member. |
Platform.AmrInvalid | 400 | A required sign-in method is 1–20 lower-case letters, digits, '-' or '_' (e.g. hwk, otp, mfa). |
Platform.AmrNotInUse | 422 | Sign in with this method before requiring it for yourself, or you would lose platform access. |
Platform.ConfirmationMismatch | 400 | Type the new owner's email address exactly to confirm. |
Platform.EmailInvalid | 400 | Enter a valid email address. |
Platform.EmailUnknown | 422 | This operator's email address is not known yet: they need to sign in once first. |
Platform.MemberNotFound | 404 | The platform member does not exist. |
Platform.MemberRemoved | 422 | This person is no longer a platform member. |
Platform.NotOwner | 422 | Only the current owner can hand over ownership. |
Platform.OwnerCannotBeRemoved | 422 | The platform owner cannot be removed: transfer ownership first. |
Platform.SubjectInvalid | 400 | The identity provider subject is missing or too long. |
Platform.TransferTargetInvalid | 422 | Ownership can only go to another active operator. |
Quality
| Code | HTTP | Message |
|---|---|---|
Quality.IncidentNotFound | 404 | The incident was not found. |
Quality.IncidentNotOpen | 409 | Only an open incident can be acknowledged. |
Quality.IncidentResolved | 409 | The incident is already resolved. |
Quality.InvalidAsset | 400 | The asset reference is not valid. |
Quality.MetricNotFound | 404 | The metric was not found on the model's main branch. |
Quality.NoImportFiles | 400 | Upload at least one dbt schema file, Great Expectations suite or a zip of them. |
Quality.NothingScanned | 409 | The source has not been scanned yet: scan it first. |
Quality.RegexUnsupported | 422 | This source has no regular expressions: give the rule a LIKE pattern. |
Quality.RuleNotActive | 409 | Only an active rule can be paused. |
Quality.RuleNotFound | 404 | The quality rule was not found. |
Quality.RuleNotPaused | 409 | Only a paused rule can be resumed. |
Quality.RuleNotProposed | 409 | Only a suggested (proposed) rule can be accepted or rejected. |
Quality.RuleRejected | 409 | A rejected rule cannot be changed or run. |
Quality.RunNotFound | 404 | The quality run was not found. |
Quality.SourceNotFound | 404 | The data source was not found. |
Quality.SourceNotScanned | 422 | The source has not been scanned yet: imported checks are mapped onto its scanned tables. |
Quality.UnknownColumns | 400 | The table or a column does not exist in the latest scan of the source. |
Quality.UnknownImportFormat | 400 | Unknown import format. Use dbt or great_expectations. |
Query
| Code | HTTP | Message |
|---|---|---|
Query.AmbiguousJoinPath | 422 | "…" can be reached from … in more than one way (…). Address it through a role name. |
Query.DimensionNotAllowed | 422 | "…" is not an allowed dimension of …; it can be sliced by …. |
Query.DimensionNotReachable | 422 | "…" cannot be reached from … through many-to-one joins; slicing … by it would repeat (fan out) its rows. |
Query.DuplicateField | 422 | "…" is requested more than once. |
Query.ExecutionFailed | 422 | The source rejected the query (…). |
Query.InvalidFilter | 422 | Filter on "…": … |
Query.InvalidGrain | 422 | "…": … |
Query.InvalidLimit | 400 | The limit must be between 1 and …. |
Query.MultipleSources | 422 | The query reads entities from more than one source; federated queries are not supported yet. |
Query.NoMetrics | 400 | A query needs at least one metric. |
Query.NoRelease | 404 | The model has no release to serve yet. Publish a release first. |
Query.SourceNotFound | 422 | The source of the model's entities was not found. |
Query.Timeout | 422 | The query ran longer than the time limit and was cancelled on the source. |
Query.TooLarge | 400 | A query can name at most … metrics, dimensions, filters, segments and orderings. |
Query.UnknownOperator | 400 | Unknown filter operator '…'. |
Query.UnsupportedDialect | 422 | Compiling for … sources is not supported yet. |
Query.UnsupportedMetric | 422 | Metric …: … |
Query.ViewAsNotMember | 404 | The user to view as is not a member of this workspace. |
Query.ViewAsUnknownRole | 400 | View as Owner, Admin, Steward, Modeler, Analyst or Viewer. |
Serving
| Code | HTTP | Message |
|---|---|---|
Serving.ApiKeyNotAllowed | 403 | This API key may not query this endpoint. |
Serving.ConversationFull | 422 | This conversation is full. Start a new conversation to keep asking. |
Serving.ConversationNotFound | 404 | The conversation was not found. |
Serving.EndpointDisabled | 403 | The serving endpoint is disabled. |
Serving.EndpointNotFound | 404 | The serving endpoint was not found. |
Serving.InvalidCacheTtl | 400 | The cache TTL is 0 (no caching) to … seconds. |
Serving.InvalidExposure | 400 | Exposed metrics and dimensions are at most 500 names each, 1–200 characters. |
Serving.InvalidName | 400 | An endpoint name is 1–120 characters. |
Serving.InvalidQuestion | 400 | A question is 1–2000 characters. |
Serving.InvalidRateLimit | 400 | The rate limit is …–… requests per minute. |
Serving.InvalidSlug | 400 | An endpoint slug is 2–63 characters: lower-case letters, digits and hyphens, starting with a letter or digit. |
Serving.McpScopeRequired | 403 | This API key needs the mcp:use scope to use the MCP server. |
Serving.ModelNotFound | 404 | The model was not found in this workspace. |
Serving.NoProposal | 422 | This answer does not propose a metric. |
Serving.NoReleasedModel | 422 | No model of this workspace has a release yet. Publish a release to ask questions about it. |
Serving.ProposalAlreadyDrafted | 409 | This proposal is already in a change request. |
Serving.PruneFailed | 500 | Pruning the query log failed for at least one tenant. |
Serving.SlugTaken | 409 | Another endpoint already uses this slug. |
Serving.SqlInterfaceDisabled | 403 | The SQL interface is not enabled for this tenant. An Owner can turn it on in Settings › Serving. |
Serving.SqlNotPermitted | 403 | This endpoint does not expose compiled SQL to you (ask a modeler to enable "Expose SQL"). |
Serving.SqlScopeRequired | 403 | This API key needs the serving:query scope to use the SQL interface. |
Serving.TurnNotFound | 404 | The answer was not found in this conversation. |
Serving.UnknownResource | 404 | There is no such resource. |
Sources
| Code | HTTP | Message |
|---|---|---|
Sources.AgentNotAllowed | 400 | Only sources connected through a private agent name an agent. |
Sources.AgentPoolUnavailable | 422 | The chosen agent pool has no enrolled agent in this workspace. |
Sources.AgentRequired | 400 | Choose the private agent this source connects through. |
Sources.AgentSecretNameInvalid | 400 | Enter the name of the secret on the agent: letters, digits, '.', '_' or '-' (up to 100 characters). |
Sources.AgentTargetAmbiguous | 400 | Choose either one private agent or an agent pool, not both. |
Sources.AgentUnavailable | 422 | The chosen private agent does not exist in this workspace or was revoked. |
Sources.BlockedHost | 422 | That address is on a private or internal network. Use a public address, or connect through a private agent. |
Sources.Deleted | 422 | The data source has been deleted. |
Sources.HostNotAllowed | 422 | … sources connect only to …. Enter the provider host, or ask an administrator to allow this one. |
Sources.HostRequired | 400 | Enter the host name. |
Sources.KindUnsupported | 422 | This kind of source is not available yet. |
Sources.NameInvalid | 400 | The name must be 1–80 characters. |
Sources.NameTaken | 409 | A data source with this name already exists in the workspace. |
Sources.NotFound | 404 | The data source was not found. |
Sources.ProfilingInvalid | 400 | The profiling policy is out of range. |
Sources.SampleUnavailable | 422 | Sample data isn't available here. Connect your own database instead. |
Sources.SecretHeldByAgent | 400 | This source connects through a private agent: its secret stays on the agent. Do not send it to Keel. |
Sources.SecretRequired | 400 | Enter the password or key. |
Status
| Code | HTTP | Message |
|---|---|---|
Status.ComponentsInvalid | 400 | Pick at least one affected component from the status page's list. |
Status.EmailInvalid | 400 | Enter a valid email address. |
Status.IncidentNotFound | 404 | The incident does not exist. |
Status.IncidentResolved | 422 | The incident is resolved; open a new one. |
Status.LinkInvalid | 400 | This link is invalid or has expired. |
Status.MessageInvalid | 400 | Write an update of 3–… characters. |
Status.NoticeNotReady | 500 | The incident update is not visible yet. |
Status.NoticePayloadInvalid | 400 | The status notice job has no incident. |
Status.TitleInvalid | 400 | Give the incident a title of 3–… characters. |
Support
| Code | HTTP | Message |
|---|---|---|
Support.AuditUnavailable | 500 | The customer's audit log could not record this support session's activity, so nothing was done. Try again shortly. |
Support.DurationInvalid | 400 | Support access lasts between 1 and … hours. |
Support.GrantNotActive | 422 | There is no active support access to revoke. |
Support.NoConsent | 403 | The tenant's Owner has not granted support access, or it has expired or been revoked. |
Support.NotConfigured | 422 | Contact support is not set up for this deployment. Ask your administrator for the support address. |
Support.ReadOnly | 403 | A support session is read-only: changes are refused. |
Support.ReasonInvalid | 400 | Give a reason of …–… characters. |
Support.SessionEnded | 422 | The support session has already ended. |
Support.SessionInvalid | 403 | The support session is not active: it ended, expired, or the customer withdrew consent. |
Support.SessionNotFound | 404 | The support session does not exist. |
Tenancy
| Code | HTTP | Message |
|---|---|---|
Tenancy.Missing | 401 | The request has no tenant context. |
Tool
| Code | HTTP | Message |
|---|---|---|
Tool.Unknown | 400 | There is no tool named '…'. Tools: …. |