Look up a Result error code, an SDK exception class, or a qodercli exit code, and decide how to handle it.
This page is the reference for error identity: given a code, an exception class, or an exit code, what it means and how to handle it. If you have a symptom rather than a code — a hang at startup, a tool the agent ignores, a setting that appears to have no effect — start from Troubleshooting, which is indexed by observed behavior.
Qoder Agent SDK reports task failures, SDK failures, and process exits separately. Handle the most specific signal available instead of treating every non-success condition as an exception.
The
Future runtimes can add Result subtypes. Always keep a fallback branch that records the subtype and
TypeScript exposes an optional
The following numeric codes are normalized by the current qodercli runtime and can appear in
SDK exceptions mean the application could not configure, start, control, or continue the session. They are separate from an unsuccessful Agent Result.
A Java model selection callback timeout is not delivered to the application as an exception, so
For expired credentials reported after startup, use
Custom Java SDK exceptions all extend the unchecked
The following error codes mean the session has terminated:
Closing the cursor closes its query or session asynchronously. For the full list of exceptions and error codes, see Java exception list.
Applications using the SDK should normally handle Results and SDK exceptions instead of branching directly on process exit codes. Exit codes are most useful for transport diagnostics or when qodercli is started outside the SDK.
Other exit codes or termination signals can come from the operating system, a custom runtime, or a child process. TypeScript exposes them through
For an actionable failure record, retain:
error_code in a Result message and the qodercli process exit code are different namespaces. Do not compare one with values from the other.
Recommended handling order
- Consume messages until the SDK produces a
resultor raises an exception. - For a Result, check
subtypeandis_errorfirst. Useerror_codeonly to choose a more specific recovery path when it is present. - Catch SDK exceptions around the entire iteration. Use the exception type and fields to diagnose configuration, runtime, or transport failures.
- Log the session ID, Result subtype, error code, and exception name. Do not log authentication values or full source content by default.
Result subtypes
subtype | Meaning | Recommended action |
|---|---|---|
success | The Agent completed the turn | Read result and continue or close the session |
error_during_execution | The turn stopped because of an execution, model, service, authentication, or unrecoverable tool error | Read errors; use error_code when available; retry only when the cause is transient |
error_max_turns | The Agent reached its configured turn limit | Inspect for loops or blocked tools, then increase the limit only if more turns are appropriate |
errors instead of assuming this table is exhaustive.
Handle Results
TypeScript exposes an optional number | string error_code on SDKResultMessage; Python exposes an optional numeric code on ResultMessage. TypeScript preserves CLI string codes such as storage_insufficient and unknown codes unchanged. Use the field when it is present, and do not extract a code by parsing human-readable error text.
Java's ResultMessage has no error code field. outcome() returns the normalized result SUCCESS, ERROR, or UNKNOWN, and wireSubtype(), wireIsError(), and errors() correspond to subtype, is_error, and errors. Read error_code from rawJson() when you need it.
Result error codes
The following numeric codes are normalized by the current qodercli runtime and can appear in message.error_code in the TypeScript and Python SDKs; Java reads the error_code field from ResultMessage.rawJson(). The field is optional. qodercli can also pass through a numeric service code not listed here, so preserve unknown values in logs and fall back to subtype plus errors.
Authentication and quota
| Code | Meaning | Recommended action |
|---|---|---|
105 | Login or access token expired | Obtain a valid credential and create a new session; register the authentication-expired callback |
110 | Daily usage limit reached | Wait for the usage window to reset or review the account limit |
113 | Usage quota exhausted | Review quota and plan status; do not immediately retry unchanged |
114 | Free-trial account limit reached | Review account eligibility or upgrade options |
115 | Free-user quota reached | Wait for quota renewal or review upgrade options |
116 | Team administrator Credits exhausted | Ask the team administrator to replenish or adjust Credits |
117 | Team member Credits exhausted | Ask the team administrator to assign or replenish Credits |
118 | Personal Credits exhausted | Replenish Credits or use an account with available capacity |
119 | Free usage limit for the selected model reached | Select an available model, wait for renewal, or review the plan |
122 | Billing-group Credits limit reached | Ask the billing administrator to review the group limit |
Request and policy
| Code | Meaning | Recommended action |
|---|---|---|
406 | Request blocked because of sensitive content or model refusal | Change the request or input content; do not retry it unchanged |
416 | Requested range or request shape is not satisfiable | Inspect errors, then reduce or correct the requested range |
430 | Requested capability is not supported | Upgrade to compatible SDK/qodercli versions or use a supported capability |
47902 | Maximum Agent turns reached | Inspect loops, permissions, and tool failures before increasing the turn limit |
48716 | A Hook blocked Agent execution | Inspect the relevant Hook decision and update the Hook or task |
80411 | Input content is too long | Reduce the prompt, attachments, or retained context |
80412 | Too many images or documents | Reduce the number of media attachments and retry |
Service and model runtime
| Code | Meaning | Recommended action |
|---|---|---|
500 | Request or network failure | Check connectivity and retry with bounded exponential backoff |
10408 | Request timed out | Retry with bounded backoff; reduce task scope if timeouts repeat |
10500 | Model service internal error | Retry later; retain the session ID when contacting support |
10605 | Model request is queued | qodercli normally waits and retries; if the code reaches the Result, retry later |
SDK exceptions
SDK exceptions mean the application could not configure, start, control, or continue the session. They are separate from an unsuccessful Agent Result.
| Situation | TypeScript | Python | Java | Useful fields |
|---|---|---|---|---|
| Authentication not configured | Error with code: "auth_not_configured" | Error with code: "auth_not_configured" | InvalidOptionsException | code; Java getCode() |
| PAT environment variable missing | AuthAccessTokenEnvVarError | AuthAccessTokenEnvVarError | AuthenticationException | code; Java getCode() |
| Service Account environment variable missing | AuthServiceAccountEnvVarError | AuthServiceAccountEnvVarError | — | code |
| qodercli not found or cannot start | QoderCliProcessError | CLINotFoundError / CLIConnectionError | CliNotFoundException, RuntimeInstallException, or QoderException with error code CLI_START_FAILED | message; TypeScript stderr; Python path/message; Java getCode() |
| qodercli exits unexpectedly | QoderCliProcessError | ProcessError | CliProcessException; AuthenticationException for exit code 41 | exitCode / exit_code, stderr; TypeScript signal; Java getExitCode(), getStderrTail() |
| Model selection callback times out | ModelPolicyTimeoutError | ModelPolicyTimeoutError | No exception; see the note after the table | timeoutMs / timeout_ms |
| Protocol version is incompatible | ProtocolVersionMismatchError | ProtocolVersionMismatchError | ProtocolVersionMismatchException | CLI and SDK protocol versions |
| Runtime lacks a required capability | UnsupportedCliCapabilityError | UnsupportedCliCapabilityError | UnsupportedCliCapabilityException | capability; Java capabilityState() |
| CLI returns a failure before initialization completes | QoderCliInitializationError | — | — | message, code, result |
catch cannot see it. The SDK answers the CLI with error code MODEL_RESOLUTION_TIMEOUT and sends an inbound_control_request_failed event to the diagnostics listener, with error=MODEL_RESOLUTION_TIMEOUT in detail. To detect this case, register a DiagnosticsListener and handle the turn's result through ResultMessage.outcome(), reading errors() when it is ERROR.
In TypeScript, startup() and query.initializationResult() throw QoderCliInitializationError when the CLI returns a failure Result before initialization completes. Its message preserves the CLI error text, code preserves the optional numeric or string error_code, and result contains the original Result. Cancellation remains AbortError. Failures after initialization continue to arrive as Result messages.
Machine-readable authentication configuration codes shared by the TypeScript and Python SDKs are:
code | Meaning |
|---|---|
auth_not_configured | No authentication method was provided |
auth_access_token_env_var_not_configured | The configured PAT environment variable is absent |
auth_service_account_env_var_not_configured | The configured Service Account environment variable is absent |
onAuthExpired / on_auth_expired and create a new session with a valid credential. Java has no such callback; handle AuthenticationException instead. See SDK Authentication.
Exceptions and error codes (Java)
Custom Java SDK exceptions all extend the unchecked QoderException; get the stable error code with getCode(). Argument and configuration errors are thrown synchronously at the call site; for example, a failed build() validation throws InvalidOptionsException. Startup and runtime failures are delivered through the message cursor's hasNext() / next(), the stage returned by consume(), or the stage returned by other asynchronous methods. When you wait with join(), they are wrapped in CompletionException; use getCause() to get the original exception.
The SDK never retries automatically, and isRetryable() returns false for every built-in exception. How to handle common error codes:
| Error code | How to handle |
|---|---|
INVALID_OPTIONS | Fix the configuration; retrying does not help |
AUTHENTICATION_FAILED, CLI_AUTH_FATAL | Fix the credential or account permissions, then create a new query or session |
CLI_NOT_FOUND, RUNTIME_INSTALL_FAILED, CLI_START_FAILED, UNSUPPORTED_SECURE_SECRET_TRANSPORT | Check the CLI path, the managed CLI download, and the startup environment; see Troubleshooting |
CLI_PROCESS_FAILED | Record getExitCode() and getStderrTail() |
UNSUPPORTED_CLI_CAPABILITY | The current CLI does not support the feature you called. If you specified the CLI yourself, switch to the SDK-managed pinned version; otherwise do not use the feature |
SESSION_CLOSED | The resource is closed; stop calling it and create a new session if needed |
MESSAGE_STREAM_ALREADY_CONSUMED | Each message stream can be consumed only once; openCursor() and consume() together can be called only once |
SPOOL_CAPACITY_EXCEEDED | Unconsumed messages exceeded the buffer limit. Read the message stream promptly |
QUERY_WRITE_FAILED (the one-shot query input was not written to the CLI), CONTROL_WRITE_FAILED (a control request or response was not written to the CLI), TURN_ACCOUNTING_FAILED (turn state can no longer be processed), and MESSAGE_DELIVERY_FAILED (a buffered message could not be decoded). The original session cannot be used again: close the handle and log the cause with getCause(). To continue the conversation, create a new session with the original session ID through SessionOptions.Builder.resume(String).
When a thread blocked in MessageCursor.hasNext() or next() is interrupted, it throws ConsumerInterruptedException, and the thread's interrupt flag stays set. To stop reading, close the cursor:
Java
qodercli process exit codes
Applications using the SDK should normally handle Results and SDK exceptions instead of branching directly on process exit codes. Exit codes are most useful for transport diagnostics or when qodercli is started outside the SDK.
| Exit code | Meaning |
|---|---|
0 | Process exited normally |
1 | General or unclassified failure |
41 | Authentication failure; the SDK also triggers the authentication-expired callback when configured. Java reports it as AuthenticationException with error code CLI_AUTH_FATAL |
42 | Invalid input or command-line arguments |
44 | Fatal sandbox error |
52 | Fatal configuration error |
53 | Fatal turn-limit error |
54 | Fatal tool-execution error |
130 | Cancellation or interrupt |
QoderCliProcessError.exitCode and .signal; Python exposes an available code through ProcessError.exit_code; Java exposes it through CliProcessException.getExitCode().
Logging and support
For an actionable failure record, retain:
- SDK language and version
- qodercli version from the
system/initmessage, when available session_id, Resultsubtype, optionalerror_code, anderrors- Exception class, machine-readable
code, process exit code, and signal - Whether the failure happened before initialization, during a tool call, or after a Result
Next steps
- Troubleshooting — start from a symptom instead of a code
- SDK Authentication — configure credentials and handle expiry
- Permissions — understand tool denial and approval behavior
- Hooks — diagnose Hook-blocked execution
- Session Control — interrupt and manage running sessions
- SDK References — inspect exact types for each language