brianc/node-postgres · error · Error

Invalid ${key}: ${value}

Error message

Invalid ${key}: ${value}

What it means

Thrown by toClientConfig() (reachable via parseIntoClientConfig or parse.toClientConfig) when the connection string's port value is non-empty but cannot be parsed into a valid integer by parseInt. The guard at index.js:196-198 attempts parseInt(value, 10), and if the result is NaN it throws 'Invalid port: <value>'. This prevents an invalid port from silently becoming NaN and causing a downstream connection failure with a confusing error.

Source

Thrown at packages/pg-connection-string/index.js:198

  const poolConfig = Object.entries(config).reduce((c, [key, value]) => {
    if (key === 'ssl') {
      const sslConfig = value

      if (typeof sslConfig === 'boolean') {
        c[key] = sslConfig
      }

      if (typeof sslConfig === 'object') {
        c[key] = toConnectionOptions(sslConfig)
      }
    } else if (value !== undefined && value !== null) {
      if (key === 'port') {
        // when port is not specified, it is converted into an empty string
        // we want to avoid NaN or empty string as a values in ClientConfig
        if (value !== '') {
          const v = parseInt(value, 10)
          if (isNaN(v)) {
            throw new Error(`Invalid ${key}: ${value}`)
          }

          c[key] = v
        }
      } else {
        c[key] = value
      }
    }

    return c
  }, Object.create(null))

  return poolConfig
}

// parses a connection string into ClientConfig
function parseIntoClientConfig(str) {
  return toClientConfig(parse(str))

View on GitHub (pinned to c5e8c9a57b)

Solutions

  1. Correct the port value in the connection string to a plain integer (e.g., 5432).
  2. If the port comes from an environment variable, validate it is numeric before building the connection string: Number(process.env.DB_PORT) || 5432.
  3. Use parse() directly instead of parseIntoClientConfig if you want to handle port coercion yourself.

Example fix

// before
const cfg = parseIntoClientConfig(`postgres://host:${process.env.DB_PORT}/db`);
// DB_PORT was 'undefined' (string) or 'abc'

// after
const port = Number(process.env.DB_PORT) || 5432;
const cfg = parseIntoClientConfig(`postgres://host:${port}/db`);
Defensive patterns

Strategy: validation

Validate before calling

function validatePort(connStr) {
  const url = new URL(connStr, 'postgres://base');
  const port = url.port || url.searchParams.get('port');
  if (port !== '' && port != null && isNaN(parseInt(port, 10))) {
    throw new Error(`Port value '${port}' is not a valid integer`);
  }
}

Try / catch

try {
  const config = parseIntoClientConfig(connStr);
} catch (err) {
  if (/^Invalid port:/.test(err.message)) {
    // Fix the port or use a default
    connStr = connStr.replace(/(:)[^/]+(\/)/, '$15432$2');
    config = parseIntoClientConfig(connStr);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling parseIntoClientConfig('postgres://host:abc/db') or parse.toClientConfig(parse('...?port=xyz')). Any connection string where the URL port segment or the port= query parameter contains non-numeric characters. The value '' (empty string) is explicitly allowed and skipped at line 195.

Common situations: A port value pulled from an environment variable that is undefined and stringified to 'undefined'. A typo such as port=54_32 or a copy-paste that includes a unit suffix. A dynamically constructed connection string where the port interpolation fails.

Related errors


AI-assisted analysis of brianc/node-postgres@c5e8c9a57b (2026-08-03). Data as JSON: /data/errors/f376460814a16fa6.json. Report an issue: GitHub.