sidorares/node-mysql2 · error · Error

"user" connection config property must be a string

Error message

"user" connection config property must be a string

What it means

When serialising a COM_CHANGE_USER packet, mysql2 requires the `user` property to be a string. If `changeUser()` is called with a config object whose `user` is missing or non-string (number, null, object), the packet cannot be built and the call fails fast with a clear error before any bytes hit the wire.

Source

Thrown at lib/packets/change_user.js:86

          connectAttributes[attrNames[k]],
          encoding
        );
      }
      packet.writeLengthCodedNumber(keysLength);
      for (let k = 0; k < attrNames.length; ++k) {
        packet.writeLengthCodedString(attrNames[k], encoding);
        packet.writeLengthCodedString(
          connectAttributes[attrNames[k]],
          encoding
        );
      }
    }
    return packet;
  }

  toPacket() {
    if (typeof this.user !== 'string') {
      throw new Error('"user" connection config property must be a string');
    }
    if (typeof this.database !== 'string') {
      throw new Error('"database" connection config property must be a string');
    }
    // dry run: calculate resulting packet length
    const p = this.serializeToBuffer(Packet.MockBuffer());
    return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
  }
}

module.exports = ChangeUser;

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Always pass a string `user`: `connection.changeUser({ user: String(newUser), database })`.
  2. Validate/coerce the user value before calling changeUser.
  3. Default to a sensible string when the source value is missing.

Example fix

// before
connection.changeUser({ user: req.body.userId });

// after
connection.changeUser({ user: String(req.body.userId) });
Defensive patterns

Strategy: validation

Validate before calling

function assertChangeUserOptions(opts) {
  if (typeof opts.user !== 'string') throw new TypeError('changeUser: user must be a string');
  if (typeof opts.database !== 'string') throw new TypeError('changeUser: database must be a string');
}

Type guard

function isValidChangeUserOpts(opts) {
  return opts != null && typeof opts.user === 'string' && typeof opts.database === 'string';
}

Prevention

When it happens

Trigger: Calling `connection.changeUser({ user: undefined })`, `changeUser({ user: 123 })`, or forgetting to include `user` in the options object. Also when passing a config built from unvalidated input.

Common situations: Pool-connection reuse where the new user comes from an untrusted/optional source and was not coerced to a string; a refactor that renamed a variable; passing the whole request body whose `user` field is absent.

Related errors


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