n8n-io/n8n · error · Error
Agent run was aborted
Error message
Agent run was aborted
What it means
Thrown by the Set node validator (v3.3+) when parameters.assignments is present but is not an object/record. The correct shape is an object containing an assignments array: { assignments: [...] }. A bare array, string, or number here is a structural mistake.
Source
Thrown at packages/@n8n/agents/src/runtime/loop/agent-runtime.ts:686
? { onStepEnd: options.onStepEnd ?? options.onStepFinish }
: {}),
repairToolCall: async (options) => {
return await fixToolCall(
{
toolCall: options.toolCall,
error: options.error,
},
toolMap,
);
},
};
}
/** Throw (and mark the run cancelled) if the abort scope has fired. */
private assertNotAborted(abortScope: AgentAbortScope): void {
if (abortScope.isAborted) {
this.updateState({ status: 'cancelled' });
throw new Error('Agent run was aborted');
}
}
/** Build the shared services the output sinks call into for terminal concerns. */
private createRunServices(): RunServices {
return {
runId: this.runId,
modelId: this.modelIdString,
applyCost: (usage) => this.applyCost(usage),
saveToMemory: async (list, options) => await this.memory.saveToMemory(list, options),
maybeGenerateTitle: async (list, options) => await this.maybeGenerateTitle(list, options),
flushTelemetry: async (options) => await this.telemetry.flush(options),
cleanupRun: async () => await this.cleanupRun(),
updateState: (patch) => this.updateState(patch),
emitAgentEnd: (messages) => this.eventBus.emit({ type: AgentEvent.AgentEnd, messages }),
getState: () => this.getState(),
};
}View on GitHub (pinned to 5ac6606e81)
Solutions
- Wrap the array: set parameters.assignments to { assignments: [ ...your assignment objects ] }.
- If you did not intend to set assignments, remove the key entirely (undefined is allowed and skips validation).
- Re-check the v3.3 assignment schema: each entry needs id, name, value, type.
Example fix
// before
set({
name: 'Set X',
assignments: [{ id: '1', name: 'x', value: 1, type: 'number' }],
});
// after
set({
name: 'Set X',
assignments: {
assignments: [{ id: '1', name: 'x', value: 1, type: 'number' }],
},
}); Defensive patterns
Strategy: type-guard
Validate before calling
function isRecord(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
}
// before building:
if (params.assignments !== undefined && !isRecord(params.assignments)) {
throw new Error('parameters.assignments must be an object { assignments: [...] }');
} Type guard
function isRecord(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Prevention
- Remember the v3.3 shape is { assignments: [...] }, not a bare array.
- Generate assignments from a typed factory that always wraps the array.
- Validate the outer shape before adding entries.
When it happens
Trigger: nodeVersion >= 3.3 AND params.assignments !== undefined AND isRecord(assignments) is false (it is null, an array, or a primitive).
Common situations: An AI builder writes assignments: [{...}] (an array) instead of assignments: { assignments: [{...}] }; mis-reading the v3.3 schema; flattening the structure during a refactor.
Related errors
- ${turn.errorReason.message}
- Tool name "${RECALL_MEMORY_TOOL_NAME}" is reserved while epi
- MCP server "${this.config.name}": connectionTimeoutMs must b
- MCP server "${config.name}": provide either "url" or "comman
- Episodic memory requires a resolved embedding model before r
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/c01ed181c5137206.
Report an issue: GitHub.