sidorares/node-mysql2 · error · Error

"database" connection config property must be a string

Error message

"database" connection config property must be a string

What it means

Thrown by HandshakeResponse.toPacket() when the 'database' connection-config property is present but not a string. Unlike user, database is optional (undefined is allowed and means 'no default database'), but once provided it must be a string because it is serialized into the CONNECT_WITH_DB portion of the handshake packet. The guard at handshake_response.js:128 rejects numbers/objects/booleans.

Source

Thrown at lib/packets/handshake_response.js:129

      }
      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;
    packet.skip(23);
    args.user = packet.readNullTerminatedString(encoding);
    let authTokenLength;

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Set database to a string schema name: { database: 'myapp' }
  2. Omit database entirely (or set to undefined) if you do not need a default database
  3. Coerce or validate before connect: if (config.database != null && typeof config.database !== 'string') throw ...
  4. Ensure config loaders return a string, not null, for the database key

Example fix

// before
const pool = mysql.createPool({ host: 'localhost', user: 'root', database: null });

// after
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  database: process.env.DB_NAME || 'myapp', // string or omit entirely
});
Defensive patterns

Strategy: validation

Validate before calling

function assertDatabaseConfig(config) {
  if (
    config.database !== undefined &&
    config.database !== null &&
    typeof config.database !== 'string'
  ) {
    throw new TypeError('mysql2: config.database must be a string or undefined');
  }
}

Type guard

function isDatabaseConfig(c) {
  return c == null || c.database === undefined || c.database === null || typeof c.database === 'string';
}

Prevention

When it happens

Trigger: Passing { database: null } or { database: 0 }, passing a numeric database identifier, or assigning database from a config value that resolved to a non-string. Note: omitting database or setting it to undefined does NOT trigger this error.

Common situations: Treating database as a boolean flag (e.g. { database: false }), passing a numeric tenant id instead of the schema name, deserializing config where database becomes null, or copy-paste from a config that used a different shape.

Related errors


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