Skip to main content

Troubleshooting: Orby pending-action approval

When a turn proposes an action that changes data — send a message, reassign a conversation, pause a campaign — Orby does not run it on the spot. It registers a pending action and renders an approval card in the chat. The action executes only when an operator explicitly approves it, and the window closes five minutes after the proposal. Every failure in that window carries a stable PENDING_ACTION_* code; this page maps each one to its cause and its recovery. The full platform code list lives in the error reference; this page is the runbook for the approval path. Session-token and authorization failures on the same panel are on the sibling page, Orby operator errors.

1. Why an approval window exists

Every data-changing proposal lands in a pending_agent_actions row and waits there until an operator explicitly approves or rejects it. The row records the tool, the exact arguments, and the proposing operator, so what you approve is a concrete, auditable payload — not “whatever the model meant.” Approval is a deliberate gate, not a formality: it keeps the operator in control of every write Orby performs. Approvals and rejections are audit-logged, including who acted and on which payload. The five-minute window exists so a stale proposal cannot be approved after its context has moved.

2. Code table

A sample envelope for a lapsed window — key on error.code, never on the message text:

3. Operator flow

  1. Open the Orby chat where the proposal was made. The pending action card shows the tool, its exact arguments, and the id; a custom client reads the pending_action_id off the tool_pending SSE event.
  2. To re-check whether the card is still live before approving, read the action — GET /api/v1/orby/tool-actions/:id returns the row’s status and its expires_at, so you can see the remaining window without guessing.
  3. If the card is gone or the read says the action is done, rejected, or cancelled, do not re-submit the same approve call — ask Orby to re-issue the proposal and approve the fresh card. An approve on a non-pending row is exactly what returns PENDING_ACTION_NOT_APPROVABLE.
  4. Assign approval to one operator. Pending actions belong to the proposing operator, so a teammate re-issuing the proposal is the clean way to hand a proposal over — not two people racing the same card.

4. Retry safety

None of the 409s is retriable — they re-fail deterministically on repeat. The recovery is always “new proposal, approve promptly.” Only PENDING_ACTION_PERSIST_FAILED is a transient 500 worth a single retry.

When to escalate

Escalate to support when:
  • PENDING_ACTION_PERSIST_FAILED recurs after a single retry — the proposal write is failing, not your request.
  • A 409 code appears on a proposal you are certain nobody else touched — that contradicts the single-approver flow and is worth a trace.
  • The approval card disappears before the five-minute window visibly elapses.
Include the request_id from the meta block (or the error SSE event), the pending-action id when you have it, and the tool name. The request id threads through the turn, dispatch, and approval paths, so support can pull the executor-side trace without a back-and-forth.

See also