n8n-io/n8n · error · InterpreterError
Cannot call non-function
Error message
Cannot call non-function
What it means
After resolving the callable value (from `sdkFunctions`, `variables`, or an object property), the interpreter checks `typeof func === 'function'` at interpreter.ts:295. If the resolved value isn't callable, it throws `InterpreterError`. This catches cases where you call a variable holding a non-function, or a property that doesn't exist on an object (resolves to `undefined`).
Source
Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts:296
`Allowed methods: ${allowedMethodNames().join(', ')}. ` +
'Native array/string methods are not available in SDK code; ' +
'use a Code node or an n8n expression for runtime logic.',
);
}
if (thisArg && typeof thisArg === 'object') {
func = (thisArg as Record<string, unknown>)[methodName];
}
} else {
throw new UnsupportedNodeError(
`Callee type ${node.callee.type}`,
node.callee.loc ?? undefined,
this.sourceCode,
);
}
if (typeof func !== 'function') {
throw new InterpreterError(
'Cannot call non-function',
node.loc ?? undefined,
this.sourceCode,
);
}
// Evaluate arguments
const args = node.arguments.map((arg) => this.evaluate(arg));
// Call the function
return func.apply(thisArg, args);
}
/**
* Visit a member expression (for property access, not method calls).
*/
private visitMemberExpression(node: ESTree.MemberExpression): unknown {
validateMemberExpression(node, this.sourceCode);View on GitHub (pinned to 5ac6606e81)
Solutions
- Verify the value is actually a function — check what the variable was assigned
- Use only documented SDK method names on builder objects
- Check for typos in method names against `allowedMethodNames()`
Example fix
// before
const config = { name: 'X' };
config({ extra: true }); // config is an object, not a function
// after
const wf = workflow({ name: 'X' });
wf.add({ extra: true }); Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check: verify that every call target resolves to a function // by tracing variable assignments in the SDK code
Type guard
// In the CALLER (TypeScript), after getting the interpreter result:
function isFunction(value: unknown): value is Function {
return typeof value === 'function';
}
// In SDK code, guard with typeof before calling (typeof IS supported):
// const fn = typeof x === 'function' ? x : null;
// if (fn) { fn(); } — but note: if/call blocks are not available in SDK code.
// Best: ensure the value is a function by construction. Try / catch
import { InterpreterError } from '@n8n/workflow-sdk/ast-interpreter/errors';
try {
interpretSDKCode(sdkCode, sdkFunctions);
} catch (e) {
if (e instanceof InterpreterError && e.message.includes('Cannot call non-function')) {
// verify method names against allowedMethodNames() and check variable assignments
}
throw e;
} Prevention
- Only call documented SDK builder methods on objects
- Verify that a variable holds a function before calling it (by checking its assignment)
- Avoid calling properties that may not exist on builder objects
When it happens
Trigger: Calling a variable that holds a non-function: `const x = 5; x()`. Or calling a property name that doesn't exist on a builder object: `obj.nonexistent()` resolves `func` to `undefined`, which fails the typeof check.
Common situations: Method name typo on an SDK builder; calling a variable that was assigned a literal value; accessing a property that resolves to undefined and then calling it.
Related errors
- Cannot access property on ${obj}
- ${toolName} was registered without a runSubAgent callback, a
- No cancellation handler is available for "${request.subAgent
- No monitors available
- Failed to parse agent steps
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f760f2dd4406a2a6.
Report an issue: GitHub.