n8n-io/n8n · error · Error
Agent "${this.name}" has tools requiring approval or suspend
Error message
Agent "${this.name}" has tools requiring approval or suspend/resume but no checkpoint storage. Add .checkpoint('memory') for in-process storage, or pass a persistent store (e.g. LibSQLStore, PgStore). What it means
Thrown by Agent.build() before any network connections when static or deferred tools have a suspendSchema (meaning they can suspend/resume or require approval) but no checkpoint store is configured. The library does a fast pre-check on known tool configurations so it fails immediately rather than after connecting to MCP servers. Suspendable tools need checkpoint storage to persist their suspended state across resume cycles.
Source
Thrown at packages/@n8n/agents/src/sdk/agent.ts:986
const finalTools = [...this.tools];
const configuredDeferredTools = [...this.deferredTools];
if (this.workspaceInstance) {
const wsTools = this.workspaceInstance.getTools();
finalTools.push(...wsTools);
}
const finalStaticTools = finalTools;
const finalDeferredTools = configuredDeferredTools;
// Validate checkpoint requirement from static tools and known MCP approval config
// before attempting any network connections (allows fast failure).
const staticNeedsCheckpoint =
finalStaticTools.some((t) => t.suspendSchema) ||
finalDeferredTools.some((t) => t.suspendSchema);
const mcpNeedsCheckpoint = this.mcpClients.some((c) => c.declaresApproval());
if ((staticNeedsCheckpoint || mcpNeedsCheckpoint) && !this.checkpointStore) {
throw new Error(
`Agent "${this.name}" has tools requiring approval or suspend/resume but no checkpoint storage. ` +
"Add .checkpoint('memory') for in-process storage, " +
'or pass a persistent store (e.g. LibSQLStore, PgStore).',
);
}
// Resolve tools from all MCP clients.
const mcpToolLists = await Promise.all(this.mcpClients.map(async (c) => await c.listTools()));
const mcpTools = ensureUniqueMcpToolNames(mcpToolLists.flat());
const mcpConnectionFailures = this.getMcpConnectionFailures();
// Detect collisions between direct, deferred, and MCP tools.
const staticCollisions = findDuplicateToolNames(finalStaticTools);
if (staticCollisions.length > 0) {
throw new Error(
`Static tool name collision — the following tool names resolve to duplicates: ${staticCollisions.join(', ')}`,
);
}View on GitHub (pinned to 5ac6606e81)
Solutions
- Call agent.checkpoint('memory') for in-process (non-persistent, development) checkpoint storage.
- Call agent.checkpoint(new LibSQLStore(...)) or agent.checkpoint(new PgStore(...)) for production persistent storage.
- Remove the suspendSchema from the tool if suspend/resume is not needed.
Example fix
// before
const agent = new Agent('a')
.model(m)
.instructions('...')
.tools([approvalRequiredTool]);
// after
const agent = new Agent('a')
.model(m)
.instructions('...')
.checkpoint('memory')
.tools([approvalRequiredTool]); Defensive patterns
Strategy: validation
Validate before calling
const toolsNeedCheckpoint = (tools: { suspendSchema?: unknown }[]) =>
tools.some((t) => t.suspendSchema);
if (toolsNeedCheckpoint(myTools) && !hasCheckpointStore) {
agent.checkpoint('memory'); // or a persistent store
} Prevention
- Call agent.checkpoint('memory') whenever using approval or suspend/resume tools.
- Use a persistent checkpoint store (LibSQLStore, PgStore) in production.
- Audit tool definitions for suspendSchema before building the agent.
When it happens
Trigger: Adding a tool with a suspendSchema (approval-required or suspend/resume tool) to an agent without calling agent.checkpoint('memory') or agent.checkpoint(persistentStore). Also triggered by deferred tools with suspendSchema or MCP clients that declare approval support.
Common situations: Adding an approval-gated MCP tool or a human-in-the-loop tool without setting up checkpoint persistence. Upgrading a tool to require approval but forgetting to add checkpoint storage. Developing locally with in-process tools and not realizing one was changed to suspendable.
Related errors
- Invalid memory configuration. Use: new Memory() for in-proce
- toolCallConcurrency must be a positive integer or Infinity
- Agent "${this.name}" requires a model
- Agent "${this.name}" requires instructions
- Static tool name collision — the following tool names resolv
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/d8db01e658c3901c.
Report an issue: GitHub.