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

ChangeUser.toPacket (lib/packets/change_user.js:84-87) serializes a COM_CHANGE_USER packet and validates that user is a string before writing it null-terminated. A non-string user (number, undefined-after-coalesce, object) would corrupt the packet framing, so the driver throws before serialization.

Solutions

  1. Coerce explicitly: String(opts.user).
  2. Validate typeof opts.user === 'string' before calling changeUser.
  3. Fix the upstream source so user is always a string.

Example fix

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

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

Strategy: validation

Validate before calling

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

Type guard

const isUserString = (opts) => typeof (opts && opts.user) === 'string';

Prevention

When it happens

Trigger: Calling connection.changeUser({ user: 123 }) or passing a config object whose user field is undefined/number; reusing a request body directly as changeUser options where user came in as a non-string.

Common situations: Loose env coercion (user: Number(process.env.DB_USER)); passing the entire request.user object instead of request.user.id; defaulting user with || from a missing value yielding a non-string.

Related errors


AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11). Data as JSON: /api/errors/bcb741c0163f1cff. Report an issue: GitHub.

Appendix: 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 8b1f829d37)