Errors
Vision errors are designed for safe diagnosis without revealing whether a credential, private record, grant, key, or policy object exists. Read the target App's declared schema; the preview contracts do not yet share one identical envelope.
Envelope
{
"error": {
"code": "invalid_client",
"message": "Client authentication failed.",
"requestId": "req_...",
"retryable": false
}
}
The Vision Core resource envelope carries a stable code, safe message, request ID, and server retry decision. OAuth token exchange is a protocol exception and returns OAuth-compatible error and optional error_description fields instead.
Status codes
- Name
400- Description
- Malformed or unsupported request.
- Name
401- Description
Missing, invalid, expired, or revoked authentication.
- Name
403- Description
Valid identity without the required scope or entitlement.
- Name
404- Description
Resource unavailable or intentionally non-disclosed.
- Name
429- Description
A shared rate policy denied the request. Respect
Retry-After.
- Name
503- Description
A required dependency is unavailable. Retry only when
retryableis true.
409 and 422 are also used by Apps that expose stateful commands, optimistic versions, idempotency conflicts, or domain validation. The operation page is authoritative for the statuses it can return.
App differences
- Name
Vision Core- Description
Resource errors use the nested
errorenvelope above. Token exchange uses the OAuth error shape.
- Name
CRM- Description
CRM errors include a schema version, stable uppercase code, retryable flag, UUID correlation ID, bounded field issues, and optional current-version conflict detail.
- Name
Calendar- Description
Calendar declares operation-specific errors for authentication, authorization, validation, missing resources, conflicts, and dependency failure.
- Name
Accounting- Description
Accounting distinguishes validation, authorization, missing references, conflicts, and unprocessable domain requests where declared.
Do not normalize away App-specific details before your application has recorded the safe correlation evidence it needs. Do not expose internal error bodies directly to an end user.
Retry decisions
| Failure | Default action |
|---|---|
| Invalid request or field issue | Correct the request; do not retry unchanged |
| Invalid or expired token | Obtain a valid token once; stop if the replacement is denied |
| Missing scope, entitlement, role, or record permission | Change the approved grant or workflow; do not retry |
| Not found or non-disclosed | Stop unless the business workflow explicitly permits later reconciliation |
| Idempotency or stale-version conflict | Read current state and reconcile; do not blind-retry |
429 with Retry-After | Wait for the supplied interval, add jitter, remain inside a bounded retry budget |
Dependency unavailable and retryable: true | Retry with exponential backoff and a total deadline |
| Client timeout on a mutation | Treat outcome as unknown; reconcile by idempotency key or receipt |
Handling example
Structured Vision API error
type VisionErrorBody = {
error?: {
code?: string
message?: string
requestId?: string
retryable?: boolean
details?: unknown
}
}
export class VisionApiError extends Error {
constructor(
readonly status: number,
readonly code: string,
readonly requestId: string | null,
readonly retryable: boolean,
message: string,
) {
super(message)
}
}
async function parseVisionResponse(response: Response) {
const requestId = response.headers.get('x-request-id')
const body = (await response.json().catch(() => ({}))) as VisionErrorBody
if (response.ok) return body
throw new VisionApiError(
response.status,
body.error?.code ?? 'unparseable_error',
body.error?.requestId ?? requestId,
body.error?.retryable ?? false,
body.error?.message ?? 'The Vision API request failed.',
)
}
Do not mark every 5xx retryable in client code. The resource server's decision and the operation's idempotency semantics matter.
Troubleshooting
Capture the environment, App, contract version, operation, status, stable error code, safe request/correlation ID, and timestamp. Confirm the exact origin, token audience, App entitlement, workspace, scope, and identity class. For validation errors, compare field casing, media type, enum values, nullability, timestamp offsets, and unknown properties against the operation schema.
Never send a client secret, bearer token, webhook secret, private key, cookie, complete private payload, or production database identifier in support material.
Request IDs
Vision Core returns x-request-id; CRM commonly exposes a UUID correlation ID in its error model. Preserve the identifier exactly as returned. A client-generated identifier is useful only when the server accepts and echoes it.