n8n-io/n8n · error · TypeError
workflow() requires (id: string, name: string). workflow() r
Error message
workflow() requires (id: string, name: string). workflow() requires a string id as first argument, but received ${receivedId}. Example: workflow('my-workflow-id', 'My Workflow Name') What it means
The workflow() factory requires its first argument to be a string id. A runtime TypeError guard checks typeof id === 'string' and reports the actual received type (distinguishing arrays from objects). The id is used verbatim as the workflow's stable identifier, so non-string values are rejected up front rather than causing subtle serialization issues later.
Source
Thrown at packages/@n8n/workflow-sdk/src/workflow-builder.ts:1308
options: WorkflowSettings | WorkflowBuilderOptions | undefined,
): options is WorkflowBuilderOptions {
if (!options) return false;
// WorkflowBuilderOptions has 'settings' or 'registry' as keys
// WorkflowSettings has keys like 'timezone', 'executionOrder', etc.
return 'settings' in options || 'registry' in options;
}
/**
* Create a new workflow builder
*/
function createWorkflow(
id: string,
name: string,
options?: WorkflowSettings | WorkflowBuilderOptions,
): WorkflowBuilder {
if (typeof id !== 'string') {
const receivedId = Array.isArray(id) ? 'an array' : typeof id;
throw new TypeError(
// eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string
'workflow() requires (id: string, name: string). ' +
`workflow() requires a string id as first argument, but received ${receivedId}. ` +
"Example: workflow('my-workflow-id', 'My Workflow Name')",
);
}
if (typeof name !== 'string') {
const receivedName = Array.isArray(name) ? 'an array' : typeof name;
throw new TypeError(
// eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string
'workflow() requires (id: string, name: string). ' +
`workflow() requires a string name as second argument, but received ${receivedName}. ` +
"Example: workflow('my-workflow-id', 'My Workflow Name')",
);
}
if (
options !== undefined &&
(Array.isArray(options) ||View on GitHub (pinned to 5ac6606e81)
Solutions
- Coerce the id to a string at the call site: workflow(String(myId), name).
- Fix the source so the id is already a string (e.g. store as text, or JSON.parse with a string id).
- Add a type annotation on the caller's id variable so TypeScript rejects non-strings at compile time.
Example fix
// before workflow(42, 'My Workflow'); // throws // after workflow(String(42), 'My Workflow');
Defensive patterns
Strategy: type-guard
Validate before calling
function isStringId(v: unknown): v is string {
return typeof v === 'string';
}
if (!isStringId(id)) id = String(id); Type guard
function isStringId(v: unknown): v is string {
return typeof v === 'string';
} Prevention
- Coerce numeric/DB ids to string before calling workflow(): workflow(String(id), name).
- Type the id variable as string at the source.
- Validate external input (JSON, query params) before forwarding to workflow().
When it happens
Trigger: Passing a number (e.g. a DB id), an object, an array, undefined, or null as the first argument to workflow(). Common when a caller reads an id from JSON/DB as a number and forwards it unchanged.
Common situations: Numeric IDs from a database; destructuring that yields undefined; loosely-typed glue code; migrated callers that previously passed any value.
Related errors
- workflow() requires (id: string, name: string). workflow() r
- ${fnName}() requires ${hint}, but received ${received}.
- workflow() third argument is settings, not workflow structur
- INVALID_CONNECTION
- VALIDATION_ERROR
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/012e1b59b9439f6b.
Report an issue: GitHub.