sidorares/node-mysql2 · error · TypeError

SSL profile must be an object, instead it's a

Error message

SSL profile must be an object, instead it's a ${typeof this.ssl}

What it means

After ConnectionConfig resolves the ssl option (lib/connection_config.js:146-172) — converting a string to an SSL profile and leaving other values as-is — it asserts that a truthy ssl is an object. A truthy non-object (e.g. a number, or a string that somehow bypassed conversion) indicates malformed config and throws a TypeError. A boolean true is an object-boxed Boolean? No — typeof true === 'boolean', so passing ssl: true would NOT trigger this (the code path makes ssl the boolean true only when options.ssl is absent/false); the throw fires for non-string, non-object truthy values.

Solutions

  1. Pass ssl as an object: ssl: { rejectUnauthorized: true } or as a known profile name string.
  2. Pass ssl: true for default TLS (the code accepts boolean true), or omit for no SSL.
  3. Sanitize env-derived ssl values: const ssl = process.env.SSL === 'true' ? { rejectUnauthorized: true } : false.

Example fix

// before
createConnection({ ssl: process.env.SSL_PORT }); // a number/string that is not a profile

// after
createConnection({ ssl: { rejectUnauthorized: true } });
Defensive patterns

Strategy: validation

Validate before calling

function normalizeSsl(ssl) {
  if (ssl === true) return { rejectUnauthorized: true };
  if (ssl === false || ssl == null) return false;
  if (typeof ssl === 'string') return ssl; // profile name
  if (typeof ssl === 'object') return ssl;
  throw new TypeError(`ssl must be boolean|string|object, got ${typeof ssl}`);
}
// createConnection({ ..., ssl: normalizeSsl(rawSsl) });

Type guard

const isSslOption = (v) => v === true || v === false || typeof v === 'string' || (typeof v === 'object' && v !== null);

Prevention

When it happens

Trigger: Passing ssl: 1 or ssl: 'true' where 'true' is not a known profile name (string branch resolves via getSSLProfile which would throw Unknown SSL profile first); passing a serialized JSON string that did not match a profile; passing an array as ssl.

Common situations: Reading ssl from an env var and coercing loosely (ssl: Number(process.env.SSL)); passing a config object built by a helper that returns a non-object on a missing key.

Understand the failure class

Related errors


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

Appendix: source

Thrown at lib/connection_config.js:166

        ? ConnectionConfig.getSSLProfile(options.ssl)
        : options.ssl || false;
    this.multipleStatements = options.multipleStatements || false;
    this.rowsAsArray = options.rowsAsArray || false;
    this.namedPlaceholders = options.namedPlaceholders || false;
    this.nestTables =
      options.nestTables === undefined ? undefined : options.nestTables;
    this.typeCast = options.typeCast === undefined ? true : options.typeCast;
    this.disableEval = Boolean(options.disableEval);
    this.enableCleartextPlugin = Boolean(options.enableCleartextPlugin);
    if (this.timezone[0] === ' ') {
      // "+" is a url encoded char for space so it
      // gets translated to space when giving a
      // connection string..
      this.timezone = `+${this.timezone.slice(1)}`;
    }
    if (this.ssl) {
      if (typeof this.ssl !== 'object') {
        throw new TypeError(
          `SSL profile must be an object, instead it's a ${typeof this.ssl}`
        );
      }
      // Default rejectUnauthorized to true
      this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
    }
    this.maxPacketSize = 0;
    this.charsetNumber = options.charset
      ? ConnectionConfig.getCharsetNumber(options.charset)
      : options.charsetNumber || Charsets.UTF8MB4_UNICODE_CI;
    this.compress = options.compress || false;
    this.authPlugins = options.authPlugins;
    this.authSwitchHandler = options.authSwitchHandler;
    this.clientFlags = ConnectionConfig.mergeFlags(
      ConnectionConfig.getDefaultFlags(options),
      options.flags || ''
    );
    // Default connection attributes

View on GitHub (pinned to 8b1f829d37)