vercel/ai · error · HarnessCapabilityUnsupportedError

The codex harness needs a TCP port exposed by the sandbox. C

Error message

The codex harness needs a TCP port exposed by the sandbox. Create the sandbox with `ports: [<port>]` or pass `createCodex({ port })`.

What it means

resolveBridgePort determines the TCP port the Codex bridge listens on inside the sandbox. It uses an explicit override, otherwise the first port in sandboxSession.ports; if neither exists it throws HarnessCapabilityUnsupportedError because the harness has no way to reach the bridge.

Source

Thrown at packages/harness-codex/src/codex-harness.ts:572

        sandboxHomeDir,
        turnConfigurationFingerprint,
      });
    },
  };
}

function resolveBridgePort({
  sandboxSession,
  override,
}: {
  sandboxSession: HarnessV1NetworkSandboxSession | SandboxSession;
  override: number | undefined;
}): number {
  if (override !== undefined) return override;
  if ('ports' in sandboxSession && sandboxSession.ports.length > 0) {
    return sandboxSession.ports[0];
  }
  throw new HarnessCapabilityUnsupportedError({
    harnessId: 'codex',
    message:
      'The codex harness needs a TCP port exposed by the sandbox. ' +
      'Create the sandbox with `ports: [<port>]` or pass `createCodex({ port })`.',
  });
}

function validateBasicSandboxSettings({
  sandboxSession,
  port,
  portEndpoint,
}: {
  sandboxSession: HarnessV1NetworkSandboxSession | SandboxSession;
  port: number | undefined;
  portEndpoint: HarnessV1PortEndpoint | undefined;
}): void {
  if ('getPortEndpoint' in sandboxSession) return;
  if (port == null) {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Create the sandbox with a port exposed, e.g. sandbox with `ports: [4096]`.
  2. Pass an explicit port via createCodex({ port: 4096 }).
  3. Verify sandboxSession.ports is populated if using a custom session implementation.

Example fix

// before
createCodex({ sandboxSession }); // sandbox created without ports
// after
createCodex({ port: 4096, sandboxSession }); // or create sandbox with ports: [4096]
Defensive patterns

Strategy: validation

Validate before calling

const hasPort = overridePort != null || (sandboxSession && 'ports' in sandboxSession && sandboxSession.ports?.length > 0);
if (!hasPort) throw new Error('codex harness needs an exposed sandbox port');

Type guard

function exposesPorts(s) {
  return typeof s === 'object' && s !== null && 'ports' in s && Array.isArray(s.ports) && s.ports.length > 0;
}

Try / catch

try {
  await harness.start({});
} catch (e) {
  if (/needs a TCP port exposed by the sandbox/.test(String(e?.message))) {
    // recreate sandbox with ports or pass createCodex({ port })
  } else throw e;
}

Prevention

When it happens

Trigger: Accessing the session port (resolveBridgePort) when no `port` override was passed to createCodex and the sandboxSession has no `ports` array (or it is empty).

Common situations: Creating a sandbox without declaring exposed ports; passing a port override to one code path but not the one that starts the session; switching sandbox providers whose session type lacks `ports`.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/5d160864860d3b41. Report an issue: GitHub.