Skip to content

Errors

Every non-2xx response from Opstage carries a stable error envelope. Codes are identifiers; messages are human-readable.

Envelope

ts
type ErrorEnvelope = {
  error: {
    code: string;
    message: string;
    details?: Record<string, unknown>;
  };
};

HTTP status codes follow the usual semantics:

StatusMeaning
400Validation failure
401Missing/invalid credentials
403Authenticated but not allowed (RBAC, CSRF, disabled agent)
404Resource does not exist
409Conflict (e.g. duplicate code)
410Gone (e.g. command expired)
5xxServer-side error

Common codes

CodeWhen
VALIDATION_FAILEDBody fails Zod validation; details.issues enumerates them
UNAUTHORIZEDNo / invalid session or agent token
CSRF_INVALIDUI mutation without a valid X-CSRF-Token
FORBIDDEN_ROLERBAC denied
AGENT_DISABLEDAgent is disabled by an operator
AGENT_NOT_FOUNDThe agent record no longer exists
REGISTRATION_TOKEN_EXPIREDRegistration token past expiresAt
REGISTRATION_TOKEN_REVOKEDRegistration token revoked
SERVICE_NOT_FOUNDCapsule Service does not exist in this workspace
ACTION_NOT_FOUNDAction is not declared in the catalog
ACTION_REQUIRES_CONFIRMATIONExecute body lacks confirmation: true
COMMAND_NOT_FOUNDCommand id unknown
COMMAND_EXPIREDCommand past its TTL before the agent picked it up
INTERNAL_ERRORUnhandled server error

Client-side handling

UIs should:

  • treat 401 as "log in again";
  • transparently refresh CSRF and retry once on 403 CSRF_INVALID;
  • display a friendly mapping of error.code to human copy (with error.message as fallback);
  • never assume an unrecognized code is safe to ignore — surface it to the user.

Adding new codes

New codes are additive (minor version bumps in the contracts package). Removing or renaming an existing code is a breaking change.

Code and docs released under Apache-2.0. "Xtrape", "Xtrape Capsule", and "Opstage" are trademarks of their respective owners.