n8n-io/n8n · warning · Error
No checkpoint found for runId: ${this.runId}
Error message
No checkpoint found for runId: ${this.runId} What it means
Thrown by the merge-node validator when a Merge node has fewer than two distinct connected inputs. Merge nodes combine multiple branches, so a single input defeats their purpose and usually indicates a wiring mistake (e.g. both branches connected to the same input index).
Source
Thrown at packages/@n8n/agents/src/runtime/loop/agent-runtime.ts:514
}
}
/**
* Durable-log RFC (resilience phase): re-drive a run from a `running`-status
* step checkpoint after a process crash. Unlike resume(), there is no
* pending tool call to settle — the checkpoint was written at a step
* boundary — so the loop re-enters directly at the next model call.
* `contextNotes` are appended as user messages before the model call: the
* host uses them to surface interrupted tool calls ("effect unverified —
* verify before retrying") and undrained steering corrections recovered
* from its durable event log. Tool calls are never re-executed mechanically.
*/
async crashResume(
options: { runId: string; contextNotes?: string[] } & ExecutionOptions,
): Promise<StreamResult> {
this.runId = options.runId;
const state = await this.runState.loadForCrashResume(this.runId);
if (!state) throw new Error(`No checkpoint found for runId: ${this.runId}`);
if (state.status !== 'running') {
throw new Error(
`Checkpoint for runId ${this.runId} has status '${state.status}' — crashResume only accepts step checkpoints; use resume() for suspended runs`,
);
}
// A claimed HITL resume also persists as 'running' but still carries its
// pending tool calls; re-driving it would skip settling them. Step
// checkpoints are always written with empty pendingToolCalls.
if (Object.keys(state.pendingToolCalls).length > 0) {
throw new Error(
`Checkpoint for runId ${this.runId} has pending tool calls — crashResume only accepts step checkpoints`,
);
}
const list = AgentMessageList.deserialize(state.messageList);
this.context.hydrateDeferredToolsFromList(list);
await hydrateFileParts(list.messages(), this.config.fileStore, {
threadId: state.persistence?.threadId,View on GitHub (pinned to 5ac6606e81)
Solutions
- Wire each upstream branch to a distinct input: .to(mergeNode.input(0)) and .to(mergeNode.input(1)).
- Verify the Merge node's input mode (append/combine/chooseBranch) matches how many branches you connect.
- If only one branch is genuinely needed, remove the Merge node and connect the branch directly.
Example fix
// before — both branches land on input 0 branchA.to(mergeNode); branchB.to(mergeNode); // after branchA.to(mergeNode.input(0)); branchB.to(mergeNode.input(1));
Defensive patterns
Strategy: validation
Validate before calling
function distinctInputCount(connections: Array<{ target?: { inputIndex?: number }; targetInputIndex?: number }>): number {
const set = new Set<number>();
for (const c of connections) {
const idx = c.target?.inputIndex ?? c.targetInputIndex ?? 0;
set.add(idx);
}
return set.size;
}
// before validating a Merge node:
if (distinctInputCount(incomingConnections) < 2) {
throw new Error('Merge node needs >= 2 distinct inputs; use .to(merge.input(0)) and .to(merge.input(1)).');
} Prevention
- Always specify the input index when connecting to a Merge node.
- Visually confirm two distinct branches enter the Merge in the canvas.
- Delete the Merge node if only one branch is needed.
When it happens
Trigger: The validator collects the set of distinct inputIndex/targetInputIndex values across all connections targeting the Merge node; if connectedInputIndices.size < 2, the issue fires. This happens when no connection targets input 1, or every connection targets the same input index.
Common situations: Both upstream branches are wired with .to(mergeNode) (defaults to input 0); an AI builder forgets to specify .input(1); a branch was deleted leaving only one input connected.
Related errors
- Reflector output must be valid JSON
- Cannot decrease maxIterations when resuming a run. Expected
- Checkpoint for runId ${this.runId} has status '${state.statu
- Checkpoint for runId ${this.runId} has pending tool calls —
- INVALID_CONNECTION
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f1a56a00bf5eed92.
Report an issue: GitHub.