Error catalog

Every Rigor API error uses the same envelope. Branch on error.code, never on error.message: messages are written for people and can change, codes cannot.

{
  "error": {
    "code": "missing_field",
    "message": "task_description is required.",
    "request_id": "req_3f9c2a71d04b8e65a1c0f2d9",
    "fix": "Provide task_description.",
    "docs": "https://plith.ai/docs/errors#missing_field",
    "details": { "field": "task_description" }
  }
}

request_id is always present; quote it when you contact support. fix, docs and details appear only when they apply. Each code below has its own link: https://plith.ai/docs/errors#<code>.

Authentication and access

Code HTTP What it means What you do
missing_api_key 401 The request carried no API key. Send your key in the x-api-key header. A free key comes from POST /api/keys.
invalid_api_key 401 The key does not exist or was revoked. Check the key with GET /api/keys/verify, or create a new one.
unauthorized 401 The request could not be tied to an organization and workspace. Send a valid x-api-key header.
forbidden 403 The resource belongs to a different organization. Use a key from the organization that owns the resource.
insufficient_permissions 403 Your role in the workspace does not allow this action. Ask a workspace owner or admin to run it, or to change your role.
tier_required 403 The feature needs a paid plan. details.required_tiers lists which. Upgrade through details.upgrade_url.
mcp_connection_limit_reached 403 Your plan's connection limit is reached. Remove a connection, or upgrade through details.upgrade_url.

Request validation

Code HTTP What it means What you do
invalid_body 400 The body is not valid JSON. Send a JSON object with content-type: application/json.
missing_field 400 A required field is absent. details.field names it. Add the field.
invalid_field 400 A field has a value the endpoint does not accept. details.field names it, and the message says why. Correct the value.
invalid_task_description 400 task_description has fewer than 2 words. Describe the task in a full sentence.
vague_task_description 400 Rigor could not tell which kind of task this is. details.classified_as is its best guess. Name the deliverable, the system, and the constraint, or set task_type yourself.
unfilled_template_placeholders 400 task_description still contains {{PLACEHOLDER}} tokens from a template. Replace every placeholder with your own values.
input_too_long 400 A field is longer than its limit. details.field, details.max_length and details.actual_length say by how much. Shorten the field. On POST /api/rigor/plan and POST /api/rigor/execute, task_description is limited to 4,000 characters and context.additional_context to 16,000. Put long material in context.additional_context rather than in the task. A request declaring task_type: "compose" is limited to 200,000 characters across both, reported with details.field task_description + context.additional_context.
invalid_action 400 action is not next, skip or abort. Send one of those 3 values.
no_workflow_ids 400 workflow_ids is missing or empty. Send an array of workflow ids.
bulk_limit_exceeded 400 workflow_ids has more entries than one request allows. Split the list into smaller requests.
webhook_url_required 400 Webhook delivery was requested without a webhook_url. Add delivery.webhook_url.
webhook_url_https 400 webhook_url does not use HTTPS. Use an https:// URL.
webhook_url_invalid 400 webhook_url is not a valid URL. Send a complete, absolute URL.
request_too_large 413 A direct-execution request has more items or characters than its task type allows. details.max gives the limit. Split the request into batches no larger than details.max.

Plan validation

Some planning failures on POST /api/rigor/plan and POST /api/rigor/execute return a flat shape instead of the envelope: error is "ValidationError", reason is the code, and details explains it.

{ "error": "ValidationError", "reason": "INVARIANT_SKIP_ATTEMPT", "details": "\"REVIEW-PROTOCOL\" is invariant and cannot be skipped." }
Reason HTTP What it means What you do
INVARIANT_SKIP_ATTEMPT 400 skip_frameworks names a step every plan must keep: task classification or the review. Remove it from skip_frameworks.
UNKNOWN_FRAMEWORK 400 only_frameworks names no framework Rigor knows, so it would restrict nothing. Use framework ids or the display names the plan response shows.
INVALID_STEP_INDEX 400 An approval_before_step index is outside the plan. Use zero-based indices smaller than the plan's step count.
PRIMARY_FRAMEWORK_ABSENT 400 Your preferences removed the step that produces this task type's deliverable. Keep that step, or choose a different task_type.
UPSTREAM_REQUIREMENTS_NOT_SATISFIED 422 This task type builds on an earlier deliverable that the request does not include. Put the earlier deliverable in context.additional_context.

Limits and billing

Code HTTP What it means What you do
rate_limit_exceeded 429 Too many requests in the current window. Wait details.retry_after seconds, or the Retry-After header, then retry.
concurrent_limit_exceeded 429 Your plan's limit on workflows running at once is reached. details.active_workflows lists them. Wait for one to finish, or upgrade through details.upgrade_url.
insufficient_credits 402 Your balance does not cover the workflow's estimate. details.shortfall is the gap. Buy credits with POST /api/billing/checkout, or choose a lighter plan.
max_budget_exceeded 402 The plan's quote is above the preferences.max_budget_usd you set, so nothing ran. details has your ceiling and the estimate. Raise max_budget_usd, lower rigor_level, or narrow the task.
workspace_budget_exceeded 402 The workflow would take the workspace past its monthly budget. This response is flat: error is the code string, with budget, used, estimated and remaining beside it. Raise the workspace budget, or reduce the plan.
deletion_rate_limited 429 Your organization has made 5 deletion requests today. Retry after midnight UTC.

Workflow state

Code HTTP What it means What you do
not_found 404 No workflow with this id is visible to your key. Check the id, and that the key belongs to the workflow's workspace.
no_plan 400 The workflow has no plan to execute. Call POST /api/rigor/plan first, or send task_description to POST /api/rigor/execute.
duplicate_task 409 The same task was submitted from this workspace in the last 5 minutes and is still running, halted or finished. Plans that were never executed, and runs that failed, were cancelled or timed out, do not count. A retry after a failure is a new run and is charged. Poll details.existing_workflow_id instead of submitting again.
workflow_has_progress 409 The workflow already has completed steps. Continue it with POST /api/rigor/resume.
invalid_status 409 The action is not allowed in the workflow's current status. details.allowed_statuses lists where it is. Check GET /api/rigor/status/{workflow_id} and act from an allowed status.
already_complete 409 Every step already has a result. Read the result from GET /api/rigor/status/{workflow_id}.
resume_conflict 409 Another resume of this workflow is in progress. Wait a few seconds and check the status before retrying.
pending_human_review 409 The workflow is waiting for a person's review. Approve or reject with POST /api/rigor/approve.
workflow_not_cancellable 409 The workflow cannot be cancelled in its current status, or needs force: true. Send force: true if the message asks for it; otherwise the workflow has already ended.
concurrent_step 409 Another step of this interactive workflow is running. Wait 2 to 3 seconds and retry.
session_expired 410 The interactive session passed its 30-minute limit. Restart it with POST /api/rigor/resume.

Chaining, direct execution, and connections

Code HTTP What it means What you do
prior_not_found 404 The workflow in prior_workflow_id was not found, or your key cannot see it. Check the id in prior_workflow_id.
prior_not_terminal 409 The workflow in prior_workflow_id has not finished yet. details.current_status is where it is now. Wait until it completes, fails, or is cancelled, then try again.
chain_depth_exceeded 422 The workflow in prior_workflow_id already builds on 10 earlier workflows, the most allowed. Start a new workflow without prior_workflow_id.
inheritance_unavailable 503 The earlier workflow could not be read, so nothing was started or charged. Retry in a few seconds.
context_too_large 422 The context carried over from the workflow in prior_workflow_id is too large. Narrow it with context_fields.
direct_mode_unavailable 422 The task type runs only in direct execution, or the request is over the default input caps under a compose allowance and so runs only there, and something in the request prevents that. details.reasons lists what. Remove what details.reasons names.
task_type_not_qualified 422 No model is qualified for this task type yet, so Rigor will not choose one. Name a model yourself on POST /api/inference/completions.
feature_not_enabled 501 The feature is switched off on this deployment. Retry later, or proceed without it.

Data deletion

Code HTTP What it means What you do
deletion_already_pending 409 A deletion request for your organization is already open. Follow details.request_id instead of opening another.
invalid_deletion_request 404 The deletion request is unknown, already processed, or its confirmation token does not match. Check the request id and token.
deletion_failed 500 Deletion stopped partway. Contact support with the request_id; the remainder is completed by hand.

Server errors

Code HTTP What it means What you do
internal_error 500 An unexpected error. Retry. If it persists, check GET /api/health and contact support with the request_id.
queue_failed 500 The workflow could not be queued. Retry in a few seconds.
plan_generation_failed 500 Rigor could not build a plan for this task. Simplify the task, or split it into smaller tasks.
model_resolution_failed 500 A temporary configuration error while choosing a model. Retry. If it persists, contact support.
plan_timeout 504 Planning took longer than 25 seconds. Shorten the task, drop optional preferences, or set task_type.
provider_exhausted 503 Every model provider for a step failed. Retry later. If it persists, contact support.
balance_unavailable 503 Your credit balance could not be read, so nothing was called, started, or charged. From /api/inference/* and from follow-ups. /api/inference/*: retry after the Retry-After header (30 seconds). Follow-ups: retry in a few seconds.
budget_unavailable 503 /api/inference/* could not read your workspace or API key monthly budget, so it did not call a model or charge you. Retry after the Retry-After header (30 seconds).

Deliverable revisions

Follow-ups on a finished deliverable: questions, rewrites, and changes. Each change makes a new version you can undo; a question makes none. insufficient_credits and workspace_budget_exceeded (above) also apply to a follow-up quote; there details has required_credits and available_credits.

Code HTTP What it means What you do
workflow_not_finished 409 Follow-ups need a finished workflow, and this one has not finished yet. details.current_status is where it is now. Wait for the workflow to complete, then try again.
operation_not_available 409 The plan needs a kind of follow-up that is not available yet. details.unavailable names it. Nothing was charged. Ask a question about the deliverable, or start a new run with prior_workflow_id.
structured_output_not_editable 409 The deliverable is data built to your output_contract schema, so a follow-up cannot rewrite it. Questions still work. Nothing was charged. Ask a question about the deliverable, or start a new run with prior_workflow_id and the changes you need.
followup_needs_approval 403 The quote is above your workspace approval threshold, or above what this API key may approve on its own. Ask an owner or admin to run it, or to raise the approval threshold.
followup_cap_exceeded 402 The quote is above the remaining follow-up cap you set on this deliverable. details has required_credits and available_credits. Raise the cap, run part of the plan, or choose a cheaper change.
quote_expired 410 The quote has expired. Quotes are valid for 30 minutes. Nothing was charged. Plan the follow-up again for a new quote.
quote_mismatch 409 The quote_id you sent is not this follow-up's current quote. Use the quote_id from the latest plan.
version_conflict 409 The current version changed after this follow-up was planned. details.current_version is the new one. Plan the follow-up again.
version_limit_reached 409 The deliverable has 50 versions, the maximum. Start a new workflow that builds on it: POST /api/rigor/execute with prior_workflow_id.
version_not_found 404 This version does not exist, or it was deleted. List versions with GET /api/rigor/workflows/{id}/versions.
cannot_delete_version 409 Version 0 and the current version cannot be deleted. details.reason says which. Make another version current first.
no_findings_to_fix 409 A fix was planned, but the run recorded no finding a follow-up can fix, or none of the finding_ids you selected can be fixed here. Nothing was quoted or charged. Read quality_breakdown, or name the change you want as another follow-up.
followup_running 409 A follow-up is already running on this deliverable: the one you named, or, when you move the current version, another one. Wait for it to finish, then try again.
agent_budget_exceeded 403 The quote is above the follow-up budget a person set on this API key, so an agent cannot run it. details has required_credits and budget_credits. Show the quote to a person, who can run it, or raise the key's follow-up budget.
subset_needs_confirmation 409 step_indices narrowed the plan to a paid charge (for example the remaining steps no longer count as an included choice) and the request did not include max_paid_credits to cover it. Nothing was started or charged. Send max_paid_credits of at least required_credits with the same step_indices, or run the whole plan.
quote_changed 409 The included follow-ups on this deliverable were used by another follow-up after this one was quoted as included, so this one now has a price. Nothing was started or charged. Read the follow-up for its quote, then run it again if you agree.
history_locked 403 The workflow is older than your plan's history window, so its content, versions and follow-ups are not available. Deleting a request's text or a version still works. Upgrade your plan to see older workflows.
workflow_running 409 You asked to delete a workflow that is still running, or that has a follow-up running. details.current_status is where it is now, when the workflow itself is running. Nothing was deleted. Cancel it with POST /api/rigor/workflows/actions, or wait for it to finish, then delete it.
children_not_finished 409 Workflows built on this one (prior_workflow_id) have not finished, so it cannot be deleted yet. details.children names them. Nothing was deleted. Wait for them to finish, or cancel or delete them, then try again.
workspace_budget_unavailable 503 The workspace budget could not be read, so nothing was started or charged. Retry in a few seconds.

Notices

Code HTTP What it means What you do
fallback_triggered 200 A step's first provider failed and a fallback provider completed it. This is a notice, not an error. Nothing.