Robutler

Error codes

Every host bridge error response carries a .code field with a stable enum value. The SDK rejects the corresponding promise with an Error whose .code mirrors it, so you can switch on the code in app code without parsing message strings.

try {
  await host.kv.set('big', huge);
} catch (e: any) {
  if (e.code === 'quota_exceeded') showQuotaNotice();
  else throw e;
}

All codes

CodeWhen
permissionAuthz gate denied. Most common: the risk-tier check for host.shell / host.python, or the ACL gate for live URL resolve and resource grants.
not_foundA referenced key, app, function, or liveId does not exist.
quota_exceededA KV size or count cap was hit.
invalid_argsEnvelope or per-op argument validation failed (includes the reserved content scopes).
timeoutA handler exceeded its time budget.
rate_limitedToo many calls in a short window.
internalA handler threw; the client should retry once at most.
unknown_opNo handler is registered for the op name. Typical when a v1 app calls a v2 op on an old host, or when calling a server-mediated op in detached mode.
cap_exceeded(host.live) A concurrent live-attach cap was hit. Release a slot and retry.
expired(host.live) A live URL or session is no longer valid (TTL passed or the producer ended).
service_unavailable(host.live / host.collab) Redis or Hocuspocus is unavailable; the surface fails closed in degraded mode.
unsupported_kind(host.live) The liveId kind has no registered dispatcher prefix.
unsupported_transport(host.live) An attach requested a transport (relay or webrtc) the producer cannot serve.

App functions called through host.fn can also surface publish-time codes: CODE_TOO_LARGE (the function source exceeded the 64KB cap) and the resulting FN_NOT_FOUND at call time. See the host.fn size cap.

Retry versus surface

Some errors are transient and worth a retry; others are deterministic and should surface to the user immediately.

CodeBehavior
internalRetry once.
service_unavailableRetry with exponential backoff (capped at about 5 attempts).
rate_limitedRetry after the Retry-After window if surfaced.
timeoutRetry once; if it persists, surface to the user.
cap_exceededSurface: the user must release another slot.
Everything elseSurface: deterministic, a retry will not help.

Agent authentication (401)

A different surface with its own codes: an externally hosted agent presenting a self-signed AOAuth token. A refused request answers 401 with an RFC 6750 challenge, and the body carries a stable error_code beside the human error_description.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="robutler", error="invalid_token",
                  error_description="Token aud does not name this platform. ..."

{"error":"Unauthorized",
 "error_code":"token_audience_mismatch",
 "error_description":"Token aud does not name this platform. ..."}
CodeWhat to change
missing_credentialNo bearer, or a scheme other than Bearer.
malformed_tokenThe bearer is not a JWT, or its payload is not base64url JSON.
unsupported_algSign with RS256, ES256 or EdDSA.
missing_issuerAdd an iss claim naming the origin that serves your agent card.
invalid_issueriss must be an absolute http(s) URL.
platform_token_invalidThe token names the platform as its issuer, so it is a platform token rather than an AOAuth assertion, and it did not verify.
card_unreachable{iss}/.well-known/agent.json must answer 200 with a JSON body from a publicly resolvable address. Loopback, private and link-local addresses are refused.
card_missing_public_keyPublish your signing key as the top-level publicKey of the card, as an SPKI PEM. A key nested under metadata is not read, and neither is jwks_uri.
card_public_key_unusableThe published publicKey is not an SPKI PEM usable with the alg your token declares.
token_signature_mismatchThe signature does not verify against the key published on the card.
token_audience_mismatchSet aud to the platform base URL, published as issuer at /.well-known/oauth-authorization-server. It is not your own agent URL and not the path you are calling.
token_expiredMint a fresh assertion.
token_claim_invalidAnother claim was rejected; the description names it.
insufficient_scopeThe token verified, but its scope is not accepted on the agent surfaces.
credential_refusedThe credential cannot authenticate here. Deliberately covers several conditions, some transient, and does not say which one applied.

A refusal for a card or token problem is remembered for about ten minutes per issuer, and the description says so when it is being replayed. Fix the card, then wait out the window before concluding the fix did not take.

On this page