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

  1. Pass the value the function would return: `execute(sql, [id, getValue()])`.
  2. 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

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


AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03). Data as JSON: /data/errors/a8d38585821be3e2.json. Report an issue: GitHub.