Errors and Status Codes

Reference for CLI exit codes, SDK exceptions, and REST API error responses.

Roboflow's developer tools share a small set of error categories, surfaced differently in each tool. This page is the cross-cutting reference.

CLI exit codes

The CLI uses four well-defined exit codes so scripts and AI agents can branch on outcome without parsing output:

Exit codeMeaning
0Success
1General error (bad input, network failure, unexpected server response)
2Authentication failure (missing or invalid API key, no workspace selected)
3Resource not found (project, version, workflow, deployment, etc. doesn't exist or isn't visible to your key)

In --json mode the CLI writes structured output to stdout on success and a JSON error object to stderr on failure, leaving stdout empty so pipelines stay safe to parse:

roboflow --json project get nonexistent 2>error.json
echo $?       # 3
cat error.json
# {"error": {"message": "Project 'nonexistent' not found", "hint": "Run 'roboflow project list' to see your projects."}}

SDK exceptions

The Python SDK raises Python exceptions on failure. The most common types you'll encounter:

ExceptionWhen
RuntimeErrorOperation is logically invalid - e.g., calling restore() on a project that isn't in Trash, or training on a version that hasn't been generated.
ValueErrorA passed argument is malformed - e.g., an unrecognized model_format for Version.download().
roboflow.adapters.rfapi.RoboflowErrorThe REST API returned a non-2xx response. The exception's string contains the server's error body.
roboflow.adapters.deploymentapi.DeploymentApiErrorEquivalent to RoboflowError for the dedicated-deployments service.
requests.exceptions.HTTPError / ConnectionErrorNetwork-level failures (DNS, TLS, timeout).

Rule of thumb: catch RuntimeError for logical issues, RoboflowError for server-side rejections, and let everything else bubble.

from roboflow.adapters import rfapi

try:
    project.restore()
except RuntimeError as e:
    print(f"Can't restore: {e}")
except rfapi.RoboflowError as e:
    print(f"Server rejected the request: {e}")

See Logging and Debugging for how to inspect the underlying HTTP request when an exception isn't enough.

REST API status codes

The REST API uses standard HTTP status codes. Roboflow-specific behavior:

StatusMeaning
200Success. Response body is JSON.
204Success, no body (used for some PATCH / DELETE endpoints).
400Malformed request - missing required field, bad shape, invalid value.
401Authentication failure. Either no api_key, an invalid one, or a key that lacks the required scope for the operation.
402Payment required. The workspace's plan does not support the requested operation. For inference, this means the model or architecture is only available on a credit-based plan, or the workspace's monthly Hosted API inference quota has been reached. The response body includes an AccessException error type.
403Forbidden. The key authenticated but doesn't have access to the target workspace or resource.
404Not found. The workspace, project, version, workflow, or other resource doesn't exist (or isn't visible to your key).
409Conflict. The resource exists in a state that prevents the requested operation (for example, restoring a version whose parent project is also in Trash).
423Locked. Workspace billing is paused - see the response body for the reason.
429Rate limited. Slow down and retry with exponential backoff.
5xxServer error. Safe to retry with backoff.

Standard error body

Errors return JSON with at least a top-level error field:

{
  "error": "Project 'nonexistent' not found"
}

Some endpoints also include a hint or a structured error object - see the per-endpoint documentation under REST API for specifics.

Required scopes

API keys carry per-resource scopes. A 401 from a write operation often means the key doesn't have the corresponding *:update or *:write scope, even if it can read the resource. See Scoped API Keys for the scope reference.

Cross-tool error mapping

SituationCLI exitSDKREST
Missing / invalid API key2RoboflowError ("401")401
Resource not found3RoboflowError ("404") / RuntimeError404
Plan limitation / quota exceeded1RoboflowError ("402")402
Bad input / malformed request1ValueError / RoboflowError ("400")400
Server error / transient1RoboflowError ("5xx")5xx

Use this table when wiring retries: a 2 / 401 should never be retried automatically (the key won't get more valid), a 3 / 404 should never be retried, but a 1 from a 5xx response is a candidate for retry with backoff.