code to recover automatically. next_action is the one-line summary you can present to the user; details carries machine-readable context.
Auth + scoping
| Code | Meaning | Recover by |
|---|---|---|
UNAUTHORIZED | No bearer token (or invalid) | Re-run the OAuth flow (chat clients) or check the API key (pk_live_*). |
SCOPE_MISSING | Bearer is valid but lacks a required scope | Re-consent to add the missing scope, or use an API key whose scope set includes it. details.missing lists the gap. |
ORG_NOT_BOUND | OAuth token isn’t bound to a workspace | Open the consent flow again and pick a workspace. |
Not found
| Code | Meaning | Recover by |
|---|---|---|
AGENT_NOT_FOUND | agent_id doesn’t exist in this org (or was deleted) | search({ kind: 'agents', query }) to find the right id. |
RUN_NOT_FOUND | run_id doesn’t exist (or was pruned by retention) | list_runs({ agent_id }) to find a live one; if the workflow needs re-running, trigger_run again. |
APP_NOT_FOUND | app_id isn’t a published app in this org | search({ kind: 'apps', query }) or pleyor://apps. |
NODE_TYPE_NOT_FOUND | The type you passed isn’t a known node type | Read pleyor://nodes for the catalog. |
MODEL_NOT_FOUND | The variant_id isn’t in the model catalog | Read pleyor://models or call suggest_model. |
VERSION_NOT_FOUND | version_id doesn’t exist for this agent | Read pleyor://agents/{id}/versions for the list. |
ASSET_NOT_FOUND | asset_id doesn’t exist or was trashed | Read pleyor://assets. |
Validation
| Code | Meaning | Recover by |
|---|---|---|
INVALID_GRAPH | Graph spec failed structural validation | validate_graph returns the specific errors with next_action hints; fix and retry. |
INCOMPATIBLE_PORT_TYPES | Edge connects two ports of incompatible types | Check pleyor://nodes/{type} for each end; use get_effective_ports for dynamic-arity nodes. |
MISSING_REQUIRED_CONFIG | A node config is missing a required field | The error details lists which field on which node; supply it. |
INPUT_SCHEMA_MISMATCH | trigger_app inputs don’t match the app’s input_schema | Read the app’s input schema, supply the expected fields with matching types. |
Execution
| Code | Meaning | Recover by |
|---|---|---|
RATE_LIMITED | Per-org or per-client rate limit hit | details.retry_after_seconds says how long to wait; back off and retry. |
INSUFFICIENT_CREDITS | Org credit balance is below the run’s estimate | Top up from your Pleyor dashboard’s billing page, or use a cheaper model (suggest_model({ use_case, budget: 'low' })). |
MODEL_PROVIDER_ERROR | The upstream provider (fal.ai, OpenAI, etc.) errored mid-execution | details.provider_error carries their message. Retry once; if persistent, swap the model variant. |
RUN_ALREADY_TERMINAL | cancel_run called on a run that’s already completed / failed / cancelled | Check pleyor://runs/{id} for the actual status. |
IDEMPOTENCY_CONFLICT | Same idempotency key, different request body | Either change the key or send the original body. |
Internal
| Code | Meaning | Recover by |
|---|---|---|
INTERNAL_ERROR | Something on our side failed unexpectedly | Retry once. If it persists, report the details.request_id. |
BAD_REQUEST | Request shape is malformed | Re-check the JSON-RPC envelope and tool argument types. |
Recovery loop (the canonical pattern)
The pleyor-workflows skill ships an “Error recovery playbook” section that the assistant follows automatically. Roughly:- Read
error.code(anddetails.step_idfor run-step failures) - Branch on the code per the table above
- Try the suggested recovery once
- If recovery itself fails, surface the error to the user with the original
next_actionhint
See also
Authentication
Scopes that drive
SCOPE_MISSING.Tools
Which tools produce which errors.