Skip to content
Try out in chatDeveloper dashboardLogin

Errors and status codes

How the API reports errors, covering HTTP status codes, problem+json bodies, task-level error events, and what to retry.

The API reports failures at three levels: HTTP errors (the request itself failed), task-level events (a Task hit a problem while running), and action results (an action was accepted but didn’t succeed). Handle all three.

HTTP errors return an RFC 7807 problem document with Content-Type: application/problem+json:

{
"type": "about:blank",
"title": "Payment Required",
"status": 402,
"detail": "Your organization is out of credits.",
"instance": "/computers"
}
FieldMeaning
typeURI reference identifying the error category
titleShort human-readable summary
statusThe HTTP status code, repeated in the body
detailOptional; specifics about this occurrence
instanceOptional; the path or resource the error relates to
StatusMeaningWhat to do
400Validation error, e.g. passing start_url on a desktop task, or an out-of-range parameterFix the request; don’t retry as-is
401Missing or invalid API keyCheck TZAFON_API_KEY; regenerate the key if needed
402Out of creditsTop up at lightcone.ai/dashboard/usage
403Key is valid but not allowed to do thisCheck the key’s scope and your plan
404Resource does not exist, or belongs to another organizationVerify the ID and that you’re using the right org’s key
429Concurrent computer limit for your plan reachedWait for a session to finish, or retry with backoff
500Internal errorRetry with backoff; contact support if persistent
502Bad gatewayRetry with backoff
503Upstream busyRetry with backoff

Several surfaces return errors in a different shape:

  • Lapsed-subscription 402 returns {"error": "light_subscription_lapsed", "status": "read_only"} (see above), not problem+json.

  • /exec streaming always responds HTTP 200 and streams newline-delimited JSON (application/x-ndjson). Each line is {"type": "stdout" | "stderr" | "exit" | "error", ...}. The stream ends with a single {"type": "exit", "code": <int>} line; code -1 means the command timed out or terminated abnormally. Check the exit line, not the HTTP status.

  • OpenAI-compatible endpoints return OpenAI-style error bodies, so existing OpenAI SDK error handling works unchanged.

  • Anthropic-compatible endpoints return Anthropic-style bodies: {"type": "error", "error": {"type": "...", "message": "..."}}.

A Task that starts successfully reports problems as stream events, not HTTP errors:

EventMeaning
config_errorThe task couldn’t start with the given configuration. Reasons include model_not_found, invalid_kind, and api_error
errorA non-terminal problem; the task is still running and may recover
failedTerminal failure. Carries status, an error_code (e.g. session_expired, exec_failed, invalid_token), and a retryable flag
max_stepsThe task hit its step limit before finishing
max_durationThe task hit its time limit before finishing
cancelledThe task was cancelled

Distinguish error (transient, keep listening) from failed (terminal). On failed, check retryable before resubmitting.

stream = client.agent.tasks.start_stream(instruction="...", kind="browser")
for event in stream:
if event.type == "failed":
if event.retryable:
pass # resubmit the task
else:
raise RuntimeError(f"Task failed: {event.error_code}")
const stream = await client.agent.tasks.startStream({ instruction: "...", kind: "browser" });
for await (const event of stream) {
if (event.type === "failed") {
if (event.retryable) {
// resubmit the task
} else {
throw new Error(`Task failed: ${event.error_code}`);
}
}
}

Computer actions (click, navigate, screenshot, …) return HTTP 200 even when the action itself fails. The ActionResult carries the outcome:

result = computer.navigate("https://example.com")
if result.status != "success":
print(f"Navigation failed: {result.error_message}")
const result = await client.computers.navigate(id, { url: "https://example.com" });
if (result.status !== "success") {
console.error(`Navigation failed: ${result.error_message}`);
}
ErrorRetry?How
429YesExponential backoff, or wait for a running session to finish
500 / 502 / 503YesExponential backoff (the SDKs do this automatically)
failed event with retryable: trueYesResubmit the task
error event (non-terminal)No actionKeep consuming the stream; the task may recover
400NoFix the request first
401NoFix the key first
402NoAdd credits first
failed event with retryable: falseNoFix the underlying cause (e.g. re-authenticate for invalid_token)