musistudio/claude-code-router · error
Codex App DevTools port was not available${lastError ? `: ${
Error message
Codex App DevTools port was not available${lastError ? `: ${redactBridgeError(lastError)}` : "."} What it means
waitForCodexDevToolsPort polls the Codex App's DevToolsActivePort file/socket until a timeout and throws this when no valid CDP port was obtained. The message includes the redacted last underlying error (redactBridgeError) explaining why each poll failed, or '.' when there was no specific error.
Source
Thrown at packages/core/src/agents/codex/media-preview-bridge.ts:242
}
}
async function waitForCodexDevToolsPort(userDataDir: string, timeoutMs: number, stopped: () => boolean): Promise<number> {
const file = path.join(userDataDir, codexDevToolsActivePortFile);
const deadline = Date.now() + timeoutMs;
let lastError: unknown;
while (!stopped() && Date.now() < deadline) {
try {
const firstLine = readFileSync(file, "utf8").split(/\r?\n/, 1)[0]?.trim();
const port = Number(firstLine);
if (Number.isInteger(port) && port > 0 && port <= 65535) return port;
lastError = new Error("DevToolsActivePort did not contain a valid port.");
} catch (error) {
lastError = error;
}
await sleep(codexMediaPreviewPollIntervalMs);
}
throw new Error(`Codex App DevTools port was not available${lastError ? `: ${redactBridgeError(lastError)}` : "."}`);
}
async function waitForCodexPageTarget(port: number, timeoutMs: number, stopped: () => boolean): Promise<DevToolsTarget> {
const deadline = Date.now() + timeoutMs;
let lastError: unknown;
while (!stopped() && Date.now() < deadline) {
try {
const response = await fetch(`http://127.0.0.1:${port}/json/list`, {
redirect: "error",
signal: AbortSignal.timeout(1_000)
});
if (!response.ok) throw new Error(`CDP target discovery returned HTTP ${response.status}.`);
const targets = await response.json() as DevToolsTarget[];
const pages = targets.filter((target) => target.type === "page" && target.webSocketDebuggerUrl);
const target = pages.find(isCodexAppPageTarget) || pages.find((entry) => (entry.url || "").startsWith("app://"));
if (target) return target;
} catch (error) {
lastError = error;View on GitHub (pinned to 99f24806c6)
Solutions
- Verify the Codex App is actually running and was launched with DevTools/CDP enabled
- Increase the timeout argument passed to waitForCodexDevToolsPort for slow startups
- Read the redacted lastError in the message to identify the underlying cause (file missing vs invalid port) and fix that (permissions, correct user-data-dir)
- Retry the bridge start after the app has fully booted
Example fix
// before const port = await waitForCodexDevToolsPort(3000, () => false); // after const port = await waitForCodexDevToolsPort(30000, () => false); // longer timeout, app started first
Defensive patterns
Strategy: retry
Validate before calling
// before bridging, confirm the DevToolsActivePort file exists and parses
import { existsSync, readFileSync } from 'node:fs';
function devToolsPortReady(path: string): boolean {
try { const [port] = readFileSync(path, 'utf8').trim().split('\n'); return /^\d+$/.test(port); }
catch { return false; }
} Type guard
null
Try / catch
try { const port = await waitForCodexDevToolsPort(timeoutMs, stopped); } catch (e) { if (e instanceof Error && e.message.includes('DevTools port was not available')) { /* relaunch app with debugging enabled, retry with backoff */ } else throw e; } Prevention
- Launch the Codex App with DevTools enabled before starting the bridge
- Use generous timeouts on slow machines
- Treat the redacted lastError text as the diagnostic source
When it happens
Trigger: Starting the media preview bridge while the Codex desktop app is not running, was launched without remote debugging enabled, crashed during startup, or when the DevToolsActivePort file is missing/contains a non-numeric port, and the poll deadline expires.
Common situations: Codex app not installed or not launched; app launched without the --remote-debugging-port/DevTools flags; slow machine where startup exceeds the configured timeout; sandboxed environment where the DevTools port file isn't readable.
Related errors
- Codex App CDP page target was not available${lastError ? `:
- Timed out waiting for ChatGPT response: + requestId
- Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.
- Grok CLI OIDC discovery timed out after ${timeoutMs}ms.
- Kimi CLI OAuth token refresh timed out after ${kimiOauthRefr
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/e56a98c69ac5522e.
Report an issue: GitHub.