coleam00/Archon · error

Run ${run.id}'s gate ('${approval.type}') only accepts 'appr

Error message

Run ${run.id}'s gate ('${approval.type}') only accepts 'approve' or 'reject' — '${decision}' is not a valid response here.

What it means

assertRespondable validates a human response to a workflow run's gate. This error means the run's gate node is not an 'approval' (or untyped) gate — e.g. it is a different gate type that does not accept simple approve/reject semantics. The engine refuses the binary decision because the gate's type defines a different response contract.

Source

Thrown at packages/core/src/operations/workflow-operations.ts:896

}

/**
 * Validate that `decision` is legal for the gate `run` is paused at, WITHOUT
 * mutating anything (mirrors `assertApprovable`'s read-only-precheck role for
 * CLI `--detach`). `approve`/`reject` are always legal (delegated to the
 * existing `approveWorkflow`/`rejectWorkflow` machinery by `respondToWorkflow`
 * — this function is not consulted for those two ids). Any OTHER decision is
 * legal only for a plain gate node (`approval`/`undefined` suspend type) whose
 * author explicitly declared `approval.decisions:` (`decisionsAuthored`) —
 * `writeback`/`interactive_loop`/`child_workflow` pauses have no author-
 * declared vocabulary and accept only approve/reject; a legacy gate (no
 * `decisions:` authored) also only ever has the synthesized approve/reject
 * pair (#2707 step 2).
 */
export function assertRespondable(run: WorkflowRun, decision: string): ApprovalContext {
  const approval = assertApprovable(run);
  if (approval.type !== 'approval' && approval.type !== undefined) {
    throw new Error(
      `Run ${run.id}'s gate ('${approval.type}') only accepts 'approve' or 'reject' — ` +
        `'${decision}' is not a valid response here.`
    );
  }
  if (approval.decisionsAuthored !== true) {
    throw new Error(
      `Run ${run.id}'s gate only accepts 'approve' or 'reject' — '${decision}' is not one of its ` +
        'declared decisions. Declare `approval.decisions:` on the gate node to author a broader vocabulary.'
    );
  }
  const declaredIds = (approval.decisions ?? []).map(d => d.id);
  if (!declaredIds.includes(decision)) {
    throw new Error(
      `Run ${run.id}'s gate does not declare decision '${decision}'. Declared decisions: ` +
        `${declaredIds.join(', ')}.`
    );
  }
  return approval;

View on GitHub (pinned to 0773b97458)

Solutions

  1. Check the run's current gate node and confirm its approval.type; use the response vocabulary that gate type actually accepts.
  2. If the gate should be a plain approval, change the workflow node so approval.type is 'approval' (or unset).
  3. If the gate intentionally declares a broader vocabulary, author approval.decisions on the node and respond with one of those decision ids instead.
  4. Update callers (CLI/scripts/platform handlers) to inspect the gate type via the run status API before responding.

Example fix

// before
await respondToWorkflow(runId, 'approve');
// after
const run = await getWorkflowRun(runId);
if (run.gate?.type === 'approval' || run.gate?.type === undefined) {
  await respondToWorkflow(runId, 'approve');
} else {
  await respondToWorkflow(runId, 'request_changes'); // a declared decision
}
Defensive patterns

Strategy: validation

Validate before calling

const gate = run.currentGate;
if (gate && gate.type !== 'approval' && gate.type !== undefined) {
  throw new Error(`Gate type '${gate.type}' does not accept approve/reject`);
}

Type guard

function isPlainApprovalGate(gate) {
  return gate === undefined || gate.type === undefined || gate.type === 'approval';
}

Try / catch

try {
  await respondToWorkflow(runId, decision);
} catch (e) {
  if (e.message.includes("only accepts 'approve' or 'reject'")) {
    const run = await getWorkflowRun(runId);
    // inspect run.gate.type and re-route the response
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling workflowRespondCommand, the 'approval' operation, or the API route POST respond with decision 'approve' or 'reject' against a run whose current gate node has approval.type set to something other than 'approval' (or undefined).

Common situations: A workflow was edited to use a custom gate type but an old bot command, Slack button, or CLI script still sends 'approve'; an automated integration hardcodes approve/reject for all gates; a run resolved a different gate type than the responder expected.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/a082bcd1efea87cc. Report an issue: GitHub.