sidorares/node-mysql2 · error · TypeError
Bind parameters must be array if namedPlaceholders…
Error message
Bind parameters must be array if namedPlaceholders parameter is not enabled
What it means
In Connection.execute (lib/base/connection.js:782-788), after resolving named placeholders, if options.values is truthy but not an Array, the driver throws because positional ? placeholders require an array. Passing an object of named values is only valid when config.namedPlaceholders is enabled; otherwise the driver cannot map keys to ? slots.
Solutions
- Pass an array: connection.execute(sql, [1]).
- Or enable named placeholders: createConnection({ ..., namedPlaceholders: true }) and use :name in SQL with a params object.
- If building params dynamically, wrap with Array.from(...) or validate Array.isArray before the call.
Example fix
// before
connection.execute('SELECT * FROM t WHERE id = ?', { id: 1 });
// after (positional)
connection.execute('SELECT * FROM t WHERE id = ?', [1]);
// after (named)
connection.execute('SELECT * FROM t WHERE id = :id', { id: 1 }); // needs namedPlaceholders: true Defensive patterns
Strategy: validation
Validate before calling
function assertBindArray(values) {
if (values && !Array.isArray(values)) {
throw new TypeError('Pass an array for positional placeholders, or enable namedPlaceholders for an object.');
}
}
// assertBindArray(values) before conn.execute(sql, values); Type guard
const isBindArray = (v) => Array.isArray(v);
Prevention
- Standardize on positional arrays across the codebase unless named placeholders are deliberately enabled.
- Lint against passing object literals to .execute() in modules without namedPlaceholders.
When it happens
Trigger: Calling connection.execute('SELECT * FROM t WHERE id = ?', { id: 1 }) without namedPlaceholders; passing a Map or object where an array is expected; mixing the named-parameter style from another driver (pg, mysql2 promise) into a positional execute call.
Common situations: Copy-paste from a pg/node-postgres codebase that uses object params; refactoring a query helper that previously built arrays; confusion between ? and :name placeholder styles.
Related errors
- Bind parameters must not contain function(s). To pass the…
- Bind parameters must not contain undefined. To pass SQL…
- Bind parameters must not contain undefined
- "database" connection config property must be a string
- "database" connection config property must be a string
AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11).
Data as JSON: /api/errors/3bf99159891e2645.
Report an issue: GitHub.
Appendix: source
Thrown at lib/base/connection.js:785
} else {
options.values = options.values || values;
}
} else if (typeof values === 'function') {
// execute(sql, cb)
cb = values;
options.sql = sql;
options.values = undefined;
} else {
// execute(sql, values, cb)
options.sql = sql;
options.values = values;
}
this._resolveNamedPlaceholders(options);
// check for values containing undefined
if (options.values) {
//If namedPlaceholder is not enabled and object is passed as bind parameters
if (!Array.isArray(options.values)) {
throw new TypeError(
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
);
}
options.values.forEach((val) => {
//If namedPlaceholder is not enabled and object is passed as bind parameters
if (!Array.isArray(options.values)) {
throw new TypeError(
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
);
}
if (val === undefined) {
throw new TypeError(
'Bind parameters must not contain undefined. To pass SQL NULL specify JS null'
);
}
if (typeof val === 'function') {
throw new TypeError(
'Bind parameters must not contain function(s). To pass the body of a function as a string call .toString() first'View on GitHub (pinned to 8b1f829d37)