{"record":{"id":"ca03e535aca84b11","repo":"jackwener/OpenCLI","slug":"cdp-not-reachable-at-manualendpoint","errorCode":null,"errorMessage":"CDP not reachable at ${manualEndpoint}","messagePattern":"CDP not reachable at (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"critical","filePath":"src/execution.ts","lineNumber":256,"sourceCode":"    command: fullName(cmd),\n    args: kwargs,\n    startedAt: Date.now(),\n  };\n  await emitHook('onBeforeExecute', hookCtx);\n\n  let result: unknown;\n  try {\n    if (siteSession !== null) {\n      const electron = isElectronApp(cmd.site);\n      let cdpEndpoint: string | undefined;\n\n      if (electron) {\n        // Electron apps: respect manual endpoint override, then try auto-detect\n        const manualEndpoint = process.env.OPENCLI_CDP_ENDPOINT;\n        if (manualEndpoint) {\n          const port = Number(new URL(manualEndpoint).port);\n          if (!await probeCDP(port)) {\n            throw new CommandExecutionError(\n              `CDP not reachable at ${manualEndpoint}`,\n              'Check that the app is running with --remote-debugging-port and the endpoint is correct.',\n            );\n          }\n          cdpEndpoint = manualEndpoint;\n        } else {\n          cdpEndpoint = await resolveElectronEndpoint(cmd.site);\n        }\n      }\n\n      const BrowserFactory = getBrowserFactory(cmd.site);\n      // Requirement vs preference: --profile / OPENCLI_PROFILE route strictly;\n      // the config default is a soft preference the daemon arbitrates.\n      const profileSelection = resolveProfileSelection(opts.profile);\n      const profileRouting = profileRouteParams(profileSelection);\n      const contextId = profileSelection?.contextId;\n      const internal = cmd as InternalCliCommand;\n      const session = resolveAdapterBrowserSession(cmd, siteSession);","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/execution.ts#L238-L274","documentation":"This CommandExecutionError is thrown by executeCommand for Electron targets when the environment variable OPENCLI_CDP_ENDPOINT is set: the library parses its port and probes the Chrome DevTools Protocol endpoint (probeCDP). If the probe fails, the manually configured endpoint is unreachable, so the command cannot attach and execution is aborted with guidance about --remote-debugging-port. It is a connectivity/configuration error, not an argument error.","triggerScenarios":"OPENCLI_CDP_ENDPOINT is set to an endpoint whose host:port does not answer CDP — the Electron app was not launched with --remote-debugging-port=<port>, the app isn't running yet, a wrong port/host is configured, or a firewall blocks the connection so probeCDP(port) returns false.","commonSituations":"Forgetting to pass --remote-debugging-port when launching the Electron app; stale OPENCLI_CDP_ENDPOINT pointing at a previous run's port; the app crashed or restarted on a different debug port; running inside a container/VM where localhost doesn't reach the app; port already occupied so the app's debugger never started.","solutions":["Launch the Electron app with --remote-debugging-port=<port> matching the port in OPENCLI_CDP_ENDPOINT, then retry the command.","Verify the endpoint with curl: `curl http://<host>:<port>/json/version` — if it doesn't return JSON, fix the URL/port in OPENCLI_CDP_ENDPOINT.","Confirm the app is actually running and the debug port wasn't taken (a busy port makes Chromium skip remote debugging); restart the app on a free port.","If you don't need a manual endpoint, unset OPENCLI_CDP_ENDPOINT so the library uses its CDP auto-detection path instead."],"exampleFix":"// before\nexport OPENCLI_CDP_ENDPOINT=http://127.0.0.1:9223\n$ mycli inspect   // CDP not reachable at http://127.0.0.1:9223 (app launched without debug port)\n\n// after\n$ electron . --remote-debugging-port=9223 &\nexport OPENCLI_CDP_ENDPOINT=http://127.0.0.1:9223\n$ mycli inspect","handlingStrategy":"fallback","validationCode":"async function assertCdpReachable(endpoint) {\n  const port = Number(new URL(endpoint).port);\n  try {\n    const res = await fetch(`http://127.0.0.1:${port}/json/version`);\n    if (!res.ok) throw new Error(`CDP returned ${res.status}`);\n  } catch (e) {\n    throw new Error(`CDP not reachable at ${endpoint}: ${e.message}`);\n  }\n}\n// before running commands: if (process.env.OPENCLI_CDP_ENDPOINT) await assertCdpReachable(process.env.OPENCLI_CDP_ENDPOINT);","typeGuard":null,"tryCatchPattern":"try {\n  await executeCommand(cmd, kwargs);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /CDP not reachable/.test(err.message)) {\n    delete process.env.OPENCLI_CDP_ENDPOINT; // fall back to CDP auto-detection\n    await executeCommand(cmd, kwargs);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always launch the Electron app with --remote-debugging-port matching OPENCLI_CDP_ENDPOINT.","Curl http://127.0.0.1:<port>/json/version to verify the endpoint before running commands.","Ensure the configured port is free at app startup; a busy port disables remote debugging.","In containers/VMs, point the endpoint at an address reachable from the CLI process, not just the app's localhost."],"tags":["cdp","electron","network","environment-variable"],"backgroundTag":"cdp-not-reachable","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}