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
- Check the run's current gate node and confirm its approval.type; use the response vocabulary that gate type actually accepts.
- If the gate should be a plain approval, change the workflow node so approval.type is 'approval' (or unset).
- If the gate intentionally declares a broader vocabulary, author approval.decisions on the node and respond with one of those decision ids instead.
- 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
- Fetch run status and inspect the gate type before sending any decision.
- Keep platform button handlers typed per gate type, not a universal approve/reject.
- Declare approval.decisions when you need custom response vocabulary.
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
- Run ${run.id}'s gate only accepts 'approve' or 'reject' — '$
- Run ${run.id}'s gate does not declare decision '${decision}'
- Invalid --status '${opts.status}'. Valid: ${workflowRunStatu
- Cannot signal a non-event workflow wait
- Node '${consumerId}' binding '${name}': an object value must
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/a082bcd1efea87cc.
Report an issue: GitHub.