sidorares/node-mysql2 · error · TypeError

Bind parameters must not contain undefined

Error message

Bind parameters must not contain undefined

What it means

toParameter() is the low-level encoder for prepared-statement (binary protocol) bind values. It rejects `undefined` for the same reason the higher-level execute() check does: SQL has no representation for undefined, and the value must be `null` to mean SQL NULL. This is the final backstop on the encode path.

Source

Thrown at lib/packets/encode_parameter.js:24

function isJSON(value) {
  return (
    Array.isArray(value) ||
    value.constructor === Object ||
    (typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
  );
}

function toParameter(value, encoding, timezone, jsonAsString) {
  let type = Types.VAR_STRING;
  let length;
  let writer = function (value) {
    // eslint-disable-next-line no-invalid-this
    return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
  };
  if (value !== null) {
    switch (typeof value) {
      case 'undefined':
        throw new TypeError('Bind parameters must not contain undefined');

      case 'number':
        type = Types.DOUBLE;
        length = 8;
        writer = Packet.prototype.writeDouble;
        break;

      case 'boolean':
        value = value | 0;
        type = Types.TINY;
        length = 1;
        writer = Packet.prototype.writeInt8;
        break;

      case 'object':
        if (Object.prototype.toString.call(value) === '[object Date]') {
          type = Types.DATETIME;
          length = 12;

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Sanitise the bind array so every undefined becomes null before execute: `values = values.map(v => v === undefined ? null : v)`.
  2. Ensure you go through Connection.execute()/pool.execute() which validates first.
  3. Trace where the undefined value originates and fix the source.

Example fix

// before
stmt.execute([id, maybeUndef]);

// after
stmt.execute([id, maybeUndef ?? null]);
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeBinds(values) {
  return values.map((v) => (v === undefined ? null : v));
}
stmt.execute(sanitizeBinds(values));

Type guard

function bindsAreDefined(arr) {
  return Array.isArray(arr) && arr.every((v) => v !== undefined);
}

Prevention

When it happens

Trigger: An undefined value slipping into the binary execute parameter list after the higher-level execute() guard — e.g. calling the Execute command directly, a code path that builds the Execute packet without the connection.js guard, or a value that becomes undefined during parameter transformation.

Common situations: Using internal command classes directly; a prepared-statement code path that bypasses Connection.execute()'s pre-check; values mutated to undefined between validation and encoding.

Related errors


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