denoland/deno · error · TypeError

Invalid port: '${maybePort}'

Error message

Invalid port: '${maybePort}'

What it means

Thrown by Deno's internal validatePort() (ext/net/01_net.js) when the port argument is a string that Number() cannot parse (converts to NaN) while the original value itself is not NaN. The quoted form in the message distinguishes garbage strings like 'abc' from NaN or fractional inputs, which take the unquoted variant.

Source

Thrown at ext/net/01_net.js:651

      throw new TypeError(`Unsupported transport: '${transport}'`);
  }
}

function validatePort(maybePort, isServer = false) {
  // A missing port means "any available port" (port 0) for servers. Clients
  // must always specify a port to connect to, so a missing port is left as-is
  // and rejected below.
  if (isServer && (maybePort === null || maybePort === undefined)) {
    maybePort = 0;
  }
  if (typeof maybePort !== "number" && typeof maybePort !== "string") {
    throw new TypeError(`Invalid port (expected number): ${maybePort}`);
  }
  if (maybePort === "") throw new TypeError("Invalid port: ''");
  const port = Number(maybePort);
  if (!NumberIsInteger(port)) {
    if (NumberIsNaN(port) && !NumberIsNaN(maybePort)) {
      throw new TypeError(`Invalid port: '${maybePort}'`);
    } else {
      throw new TypeError(`Invalid port: ${maybePort}`);
    }
  } else if (port < (isServer ? 0 : 1) || port > 65535) {
    // Servers may bind to port 0 (OS-assigned), clients may not connect to it.
    throw new RangeError(`Invalid port (out of range): ${maybePort}`);
  }
  return port;
}

function createListenDatagram(udpOpFn, unixOpFn) {
  return function listenDatagram(args) {
    switch (args.transport) {
      case "udp": {
        const port = validatePort(args.port, true);
        const { 0: rid, 1: addr } = udpOpFn(
          {
            hostname: args.hostname ?? "0.0.0.0",

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Convert the value before the call: const port = Number(rawPort) (or parseInt(rawPort, 10)) and pass the number
  2. Validate at the config boundary (env var, CLI flag, config file) and fail fast with your own clear error
  3. When deriving a port from a URL, remember new URL(u).port is '' for scheme-default ports - fall back to 80/443 explicitly

Example fix

// before
const port = Deno.env.get("PORT");
await Deno.connect({ hostname: "db.local", port }); // TypeError: Invalid port: '...'

// after
const port = Number(Deno.env.get("PORT"));
if (!Number.isInteger(port) || port < 1 || port > 65535) {
  throw new Error(`Invalid PORT value: ${Deno.env.get("PORT")}`);
}
await Deno.connect({ hostname: "db.local", port });
Defensive patterns

Strategy: validation

Validate before calling

function parsePort(raw: string | number | undefined): number {
  const port = Number(raw);
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error(`Invalid port value: ${String(raw)}`);
  }
  return port;
}

// before any Deno.connect / Deno.listen call:
await Deno.connect({ hostname, port: parsePort(cfg.port) });

Type guard

function isValidPortValue(p: unknown): p is number {
  return typeof p === "number" && Number.isInteger(p) && p >= 0 && p <= 65535;
}

Prevention

When it happens

Trigger: Any port-validating Deno net API - Deno.connect, Deno.listen, Deno.listenTls, Deno.connectTls, Deno.listenDatagram - called with port set to a non-numeric, non-empty string: Deno.connect({ hostname: 'example.com', port: 'https' }), port: '8080 ' (trailing space), or port: 'eighty'.

Common situations: PORT read from Deno.env.get() or process.argv without Number() conversion; ports assembled from config strings with suffixes; accidentally swapping hostname and port fields; URL parsing that yields non-numeric fragments.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/65b0339961b5abc2. Report an issue: GitHub.