sidorares/node-mysql2 · error · TypeError
Bind parameters must not contain function(s). To pass the bo
Error message
Bind parameters must not contain function(s). To pass the body of a function as a string call .toString() first
What it means
Connection.execute() rejects bind values that are JS functions. A function cannot be serialised to a SQL value; this check exists because passing a callback or function reference where a value was expected is a common programming mistake (e.g. passing the wrong variable). The error message tells you to call `.toString()` explicitly if you genuinely intended to send the function's source as text.
Source
Thrown at lib/base/connection.js:794
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'
);
}
});
}
const executeCommand = new Commands.Execute(options, cb);
const prepareAndExecute = (errorCb) => {
const prepareCommand = new Commands.Prepare(options, (err, stmt) => {
if (err) {
// skip execute command if prepare failed
executeCommand.start = function () {
return null;
};
errorCb(err);
executeCommand.emit('end');
return;
}View on GitHub (pinned to 5ebe8903d6)
Solutions
- Pass the value the function would return: `execute(sql, [id, getValue()])`.
- If you truly want the function's source text: `execute(sql, [id, fn.toString()])`.
Example fix
// before
connection.execute('SELECT * FROM t WHERE id = ?', [getId]);
// after
connection.execute('SELECT * FROM t WHERE id = ?', [getId()]); Defensive patterns
Strategy: validation
Validate before calling
function assertNoFunctions(values) {
values.forEach((v, i) => {
if (typeof v === 'function') {
throw new TypeError(`Bind value at index ${i} is a function; did you mean to call it?`);
}
});
}
assertNoFunctions(values);
conn.execute(sql, values); Type guard
function hasNoFunctions(arr) {
return Array.isArray(arr) && arr.every((v) => typeof v !== 'function');
} Prevention
- Double-check that each bind value is a scalar/Date/Buffer/object, not a callable.
- Review refactors that replaced a value with its accessor function.
When it happens
Trigger: Passing a function reference into the values array: `execute(sql, [id, someCallback])`, or a variable that holds a function instead of data. Also happens when mapping over data and accidentally passing the mapper function.
Common situations: Mixing up a value and its accessor function; passing `req.body.someMethod` instead of `req.body.someField`; refactoring that left a function reference where a value used to be.
Related errors
- Bind parameters must be array if namedPlaceholders parameter
- Bind parameters must not contain undefined. To pass SQL NULL
- Bind parameters must not contain undefined
- You have tried to call .then(), .catch(), or invoked await o
AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03).
Data as JSON: /data/errors/a8d38585821be3e2.json.
Report an issue: GitHub.