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

Thrown by HandshakeResponse.toPacket() when serializing the MySQL handshake response packet. The library requires that the 'user' connection-config property be a string because it is written into the authentication packet via writeLengthCodedString. If user is undefined, a number, or any non-string type, the check at handshake_response.js:125 rejects it before any network I/O. This is a fail-fast guard against malformed config reaching the wire.

Source

Thrown at lib/packets/handshake_response.js:126

          connectAttributes[attrNames[k]],
          encoding
        );
      }
      packet.writeLengthCodedNumber(keysLength);
      for (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.serializeResponse(Packet.MockBuffer());
    return this.serializeResponse(Buffer.alloc(p.offset));
  }
  static fromPacket(packet, serverFlags = 0xffffffff) {
    const args = {};
    args.clientFlags = packet.readInt32();
    function isSet(flag) {
      return args.clientFlags & serverFlags & ClientConstants[flag];
    }
    args.maxPacketSize = packet.readInt32();
    args.charsetNumber = packet.readInt8();
    const encoding = CharsetToEncoding[args.charsetNumber];
    args.encoding = encoding;

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Ensure the user property is a string in the connection config: { user: 'root' }
  2. Validate config.user before creating the connection, e.g. if (typeof config.user !== 'string') throw ...
  3. Provide a fallback from environment: { user: process.env.DB_USER || 'root' }
  4. Check that environment variables DB_USER / MYSQL_USER are exported in the current shell or .env file

Example fix

// before
const conn = mysql.createConnection({ host: 'localhost' }); // user missing

// after
const conn = mysql.createConnection({
  host: 'localhost',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD,
});
Defensive patterns

Strategy: validation

Validate before calling

function assertUserConfig(config) {
  if (typeof config.user !== 'string' || config.user.length === 0) {
    throw new TypeError('mysql2: config.user must be a non-empty string');
  }
}
// call before createConnection / createPool
assertUserConfig(config);

Type guard

function isUserConfig(c) {
  return c != null && typeof c.user === 'string';
}

Prevention

When it happens

Trigger: Calling createConnection({ user: undefined }), createConnection({ user: 123 }), or omitting the user field entirely (so it defaults to undefined). Also triggered if a config object is built dynamically where user ends up null/number/object, or when env vars like process.env.DB_USER are unset and assigned to user.

Common situations: Loading credentials from environment variables that are not set (undefined), parsing JSON config where the user key is missing, passing a numeric user id from an internal system instead of the username string, or accidentally passing a pool/cluster config that lacks user.

Related errors


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