n8n-io/n8n · error · TypeORMError
Function parameter isn't supported in the parameters. Please
Error message
Function parameter isn't supported in the parameters. Please check "${key}" parameter. What it means
QueryBuilder.setParameter() throws TypeORMError when the value argument is a function. SQL parameter values must be serializable scalars/objects (string, number, boolean, Date, buffer, array); a function cannot be bound to a prepared-statement parameter and would produce nonsensical SQL. The check is a hard guard before storing the value in expressionMap.parameters.
Source
Thrown at packages/@n8n/typeorm/src/query-builder/QueryBuilder.ts:357
return !!entityMetadata.findRelationWithPropertyPath(relation);
});
}
/**
* Check the existence of a parameter for this query builder.
*/
hasParameter(key: string): boolean {
return this.parentQueryBuilder?.hasParameter(key) || key in this.expressionMap.parameters;
}
/**
* Sets parameter name and its value.
*
* The key for this parameter may contain numbers, letters, underscores, or periods.
*/
setParameter(key: string, value: any): this {
if (typeof value === 'function') {
throw new TypeORMError(
`Function parameter isn't supported in the parameters. Please check "${key}" parameter.`,
);
}
if (!key.match(/^([A-Za-z0-9_.]+)$/)) {
throw new TypeORMError(
'QueryBuilder parameter keys may only contain numbers, letters, underscores, or periods.',
);
}
if (this.parentQueryBuilder) {
this.parentQueryBuilder.setParameter(key, value);
}
this.expressionMap.parameters[key] = value;
return this;
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Invoke functions before passing: Date.now() not Date.now.
- Coerce/serialize the value to a primitive, Date, or array before setParameter.
- If you need dynamic SQL fragments, use string interpolation in the where clause with proper escaping, not a parameter.
- Audit setParameters object values for function members.
Example fix
// before
qb.andWhere('u.createdAt > :now', {})
.setParameter('now', Date.now); // function, throws
// after
qb.andWhere('u.createdAt > :now', {})
.setParameter('now', Date.now()); Defensive patterns
Strategy: validation
Validate before calling
function isBindableParam(v: unknown): boolean {
return v == null || ['string','number','boolean','bigint'].includes(typeof v) || v instanceof Date || Buffer.isBuffer(v) || Array.isArray(v);
}
if (!isBindableParam(value)) throw new Error('parameter value must be a scalar/Date/Buffer/array, got function'); Type guard
function isBindableValue(v: unknown): v is string | number | boolean | Date | Buffer | unknown[] | null {
return v == null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || v instanceof Date || Buffer.isBuffer(v) || Array.isArray(v);
} Prevention
- Invoke functions before passing as parameters (Date.now() not Date.now).
- Validate parameter values are scalars/Date/Buffer/array before setParameter.
- Use string interpolation for dynamic SQL fragments, not parameters.
- Audit setParameters object values for function members.
When it happens
Trigger: Calling .setParameter('key', someFunction) or .setParameters({ key: fn }). Also when passing a value that is unexpectedly a function due to a missing invocation, e.g. .setParameter('now', Date.now) instead of Date.now().
Common situations: Forgetting to invoke a function (Date.now vs Date.now()). Passing a comparator or callback by mistake. Dynamic parameter building that accidentally includes a function from user input.
Related errors
- QueryBuilder parameter keys may only contain numbers, letter
- Parameter ${key} must be a string
- Cannot perform insert query because values are not defined.
- cte.options.columnNames length (${cte.options.columnNames.le
- Provided "limit" value is not a number. Please provide a num
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/c1a69d64a9e07f3d.
Report an issue: GitHub.