jackwener/OpenCLI · error · CommandExecutionError
App launched but CDP not available on port ${port} after ${P
Error message
App launched but CDP not available on port ${port} after ${POLL_TIMEOUT_MS / 1000}s What it means
After launching the Electron app, pollForReady probes the Chrome DevTools Protocol port (probeCDP) every POLL_INTERVAL_MS until POLL_TIMEOUT_MS elapses. If CDP never answers within that window, it assumes the debug port never opened and throws this CommandExecutionError.
Source
Thrown at src/launcher.ts:347
export function electronLaunchArgs(port: number, extraArgs: string[] = []): string[] {
return [
`--remote-debugging-port=${port}`,
'--remote-allow-origins=*',
...extraArgs,
];
}
function manualElectronLaunchHint(label: string, port: number): string {
return `Start ${label} manually with --remote-debugging-port=${port} --remote-allow-origins=*, then either:`;
}
async function pollForReady(port: number): Promise<void> {
const deadline = Date.now() + POLL_TIMEOUT_MS;
while (Date.now() < deadline) {
if (await probeCDP(port, 1_000)) return;
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
}
throw new CommandExecutionError(
`App launched but CDP not available on port ${port} after ${POLL_TIMEOUT_MS / 1000}s`,
'The app may be slow to start. Try running the command again.',
);
}
/**
* Main entry point: resolve an Electron app to a CDP endpoint URL.
*
* Returns the endpoint URL: http://127.0.0.1:{port}
*/
export async function resolveElectronEndpoint(site: string): Promise<string> {
const app = getElectronApp(site);
if (!app) {
throw new CommandExecutionError(
`No Electron app registered for site "${site}"`,
'Register the app in ~/.opencli/apps.yaml or check the site name.',
);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — a slow-starting app may simply need more time.
- Quit any already-running instance of the app first so the launched instance honors the debug port.
- Verify the app is launched with --remote-debugging-port (check the custom binary/wrapper in apps.yaml doesn't strip arguments).
- Check that nothing (firewall, VPN, security software) blocks connections to localhost:<port>.
Example fix
// before: app already running without debug port $ myapp-cli open # times out: CDP not available // after $ pkill -f MyApp && myapp-cli open
Defensive patterns
Strategy: retry
Validate before calling
const isOpen = await probeCDP(port, 1000).catch(() => false);
if (!isOpen) console.warn(`CDP port ${port} not open before launch; ensure no stale app instance is running`); Type guard
function isCdpReachable(port: number): boolean {
return fetch(`http://127.0.0.1:${port}/json/version`)
.then((r) => r.ok)
.catch(() => false) as unknown as boolean;
} Try / catch
for (let attempt = 0; attempt < 3; attempt++) {
try {
const endpoint = await resolveElectronEndpoint(port);
break;
} catch (e) {
if (e instanceof CommandExecutionError && /CDP not available/.test(e.message) && attempt < 2) {
await new Promise((r) => setTimeout(r, 2000));
continue;
}
throw e;
}
} Prevention
- Quit existing app instances before launching so the debug port binds.
- Launch on a free port and pass --remote-debugging-port explicitly.
- Increase the timeout / check app startup time on slow machines.
- Confirm firewalls allow localhost connections to the chosen port.
When it happens
Trigger: resolveElectronEndpoint launches the app with --remote-debugging-port=<port>, the process starts, but probeCDP(port) keeps failing until the timeout expires (e.g. app ignores the debug flag, port blocked, or app takes longer than POLL_TIMEOUT_MS to open the listener).
Common situations: Slow machine or heavy app startup exceeding the timeout; app was already running without the debug flag so the new instance defers to it; firewall/security software blocking localhost connections; a wrapper or custom binary that drops the --remote-debugging-port argument.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Knowledge button not found
- Marketplace button not found
- Credits Usage not visible
- View all button not visible
- Add Workspace button not found
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/084574de46909751.
Report an issue: GitHub.