n8n-io/n8n · error · TypeORMError
QueryBuilder parameter keys may only contain numbers, letter
Error message
QueryBuilder parameter keys may only contain numbers, letters, underscores, or periods.
What it means
QueryBuilder.setParameter() validates the key against /^([A-Za-z0-9_.]+)$/ and throws if it fails. Parameter keys become placeholders in generated SQL; characters outside alphanumerics, underscore, and period would break parameter substitution or risk injection. Keys like 'a b', 'a-b', 'a$b' are rejected.
Source
Thrown at packages/@n8n/typeorm/src/query-builder/QueryBuilder.ts:363
*/
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;
}
/**
* Adds all parameters from the given object.
*/
setParameters(parameters: ObjectLiteral): this {
for (const [key, value] of Object.entries(parameters)) {
this.setParameter(key, value);View on GitHub (pinned to 5ac6606e81)
Solutions
- Use only letters, digits, underscore, and period in parameter keys.
- Sanitize dynamic keys: key.replace(/[^A-Za-z0-9_.]/g, '_').
- Prefer camelCase or snake_case keys consistently.
- If a hyphenated identifier is needed, alias it to a safe key and map back.
Example fix
// before
qb.andWhere('u.role = :user-role', {})
.setParameter('user-role', role); // throws
// after
qb.andWhere('u.role = :userRole', {})
.setParameter('userRole', role); Defensive patterns
Strategy: validation
Validate before calling
const PARAM_KEY = /^([A-Za-z0-9_.]+)$/;
function isValidParamKey(key: string): boolean { return PARAM_KEY.test(key); }
if (!isValidParamKey(key)) throw new Error(`invalid parameter key: ${key}`);
function sanitizeParamKey(key: string): string { return key.replace(/[^A-Za-z0-9_.]/g, '_'); } Type guard
function isValidParamKey(key: string): key is string {
return /^([A-Za-z0-9_.]+)$/.test(key);
} Prevention
- Restrict parameter keys to [A-Za-z0-9_.].
- Sanitize dynamic keys: key.replace(/[^A-Za-z0-9_.]/g, '_').
- Prefer camelCase or snake_case keys.
- Validate keys from user input before setParameter.
When it happens
Trigger: Calling .setParameter('user id', val) (space), .setParameter('user-id', val) (hyphen), or any key with special characters. Also when building keys dynamically from untrusted input that contains symbols.
Common situations: Constructing parameter keys from form field names that contain spaces or hyphens. Copying a column name verbatim as a key. Typos or copy-paste introducing invisible characters.
Related errors
- Function parameter isn't supported in the parameters. Please
- 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/9db80211fc867fde.
Report an issue: GitHub.