Skip to content
MANTYX.IO

Errors

All three SDKs raise a small typed hierarchy so you can try / except (or check err.(*mantyx.RunError)) at the granularity you need.

Error When
MantyxError (base) Any other SDK-raised condition
MantyxAuthError 401 from the server — bad / missing API key or OAuth access token. When a tokenSource is configured the SDK refreshes and retries once before raising.
MantyxScopeError 403 insufficient_scope — OAuth-only. The access token is missing one of the scopes a route demands; the requiredScopes / required_scopes / RequiredScopes field lists them so callers can drive a re-consent flow. API keys never trip this.
MantyxOAuthError Non-2xx from /api/oauth/token or /api/oauth/revoke — carries the RFC 6749 oauth_error (e.g. invalid_grant, invalid_client) plus an optional description. invalid_grant on refresh means the refresh token was revoked; the caller must re-drive sign-in.
MantyxNetworkError Transport-layer failures (DNS, TCP reset, timeout)
MantyxRunError The agent loop terminated with a non-success result, a terminal error event, or a cancelled
MantyxToolError A local tool handler threw or timed out

When the run terminates via a terminal error event (e.g. the model truncated mid-reply, the upstream provider returned a rate limit, the local-tool POST timed out), the SDKs surface the wire-level triage attributes on the run error so callers can render UI banners and drive retry policy without re-parsing the human-readable message:

Attribute (TS / Python / Go) Meaning
errorClass / error_class / ErrorClass Canonical category — "rate_limit", "overloaded", "server", "context_window", "truncation", "invalid_request", "auth", "timeout", "local_timeout", "upstream_deadline", or "unknown". New categories may land additively.
finishReason / finish_reason / FinishReason Canonical lowercase provider stop reason ("max_tokens", "refusal", "malformed_function_call", …). Mirrors the last assistant_message event’s finishReason.
partialText / partial_text / PartialText Best-effort raw bytes the model emitted before the failure. For outputSchema runs this is usually incomplete JSON that will fail JSON.parse — treat it as diagnostic data, never as a schema-conformant reply.
retryable / retryable / Retryable Coarse retry hint inherited from the pipeline’s classifier. Informational; the SDK does not retry on your behalf.

All four are optional: older runners that haven’t classified the failure yet, or non-terminal error paths, leave them unset (undefined in TS, None in Python, zero-values / nil in Go).

The errorClass taxonomy and the truncation salvage contract are both described in detail in Wire protocol §4.7 and Agent-runs protocol §7.

import {
MantyxAuthError,
MantyxNetworkError,
MantyxRunError,
MantyxToolError,
} from "@mantyx/sdk";
try {
await client.runAgent({ systemPrompt: "...", prompt: "..." });
} catch (e) {
if (e instanceof MantyxAuthError) {
console.error("rotate the API key");
} else if (e instanceof MantyxRunError) {
if (e.errorClass === "truncation") {
// The model ran out of output budget mid-reply; `e.partialText` carries
// the raw bytes emitted so far (typically incomplete JSON).
console.warn("truncated reply — JSON likely incomplete:", e.partialText);
} else {
console.error("agent failed:", e.errorClass ?? e.subtype, "", e.message);
}
} else {
throw e;
}
}
from mantyx import MantyxAuthError, MantyxRunError
try:
client.run_agent(system_prompt="...", prompt="...")
except MantyxAuthError:
print("rotate the API key")
except MantyxRunError as e:
if e.error_class == "truncation":
# The model ran out of output budget mid-reply; `e.partial_text`
# carries the raw bytes emitted so far (typically incomplete JSON).
print("truncated reply — JSON likely incomplete:", e.partial_text)
else:
print("agent failed:", e.error_class or e.subtype, "", e.message)
result, err := client.RunAgent(ctx, mantyx.RunSpec{...})
if err != nil {
var auth *mantyx.AuthError
var run *mantyx.RunError
switch {
case errors.As(err, &auth):
log.Println("rotate the API key")
case errors.As(err, &run):
if run.ErrorClass == "truncation" {
// The model ran out of output budget mid-reply; `run.PartialText`
// carries the raw bytes emitted so far (typically incomplete JSON).
log.Printf("truncated reply — JSON likely incomplete: %s", run.PartialText)
} else {
log.Printf("agent failed (%s): %s", run.Code, run.Message)
}
default:
log.Fatal(err)
}
}
Code HTTP Notes
unauthorized 401 Missing / invalid / expired bearer credential
forbidden 403 API key not authorized for this agent
insufficient_scope 403 OAuth access token is missing one of the required scopes (surfaced as MantyxScopeError with the required scope list)
not_found 404 Workspace, run, or session unknown
invalid_request 400 Body failed validation
invalid_model 400 modelId couldn’t be resolved
invalid_grant 400 OAuth refresh token or auth-code is unknown / revoked / consumed — sign in again
invalid_client 401 OAuth client_id / client_secret is wrong or the app is disabled
unknown_tool_use 404 Tool-result for an unknown toolUseId
run_terminal 409 Tool-result after run finished
rate_limited 429 Per-credential sliding window

The full list (and run-level result.subtype codes) lives in Wire protocol §10.