{"record":{"id":"052c59f9447c92f2","repo":"jackwener/OpenCLI","slug":"daemon-not-running","errorCode":"daemon-not-running","errorMessage":"Failed to start opencli daemon","messagePattern":"Failed to start opencli daemon","errorType":"exception","errorClass":"BrowserConnectError","httpStatus":null,"severity":"critical","filePath":"src/browser/daemon-lifecycle.ts","lineNumber":158,"sourceCode":"  }\n\n  if (!staleDaemonReplaced && health.state === 'profile-required') {\n    throw browserConnectErrorFromHealth(health, contextId);\n  }\n\n  if (staleDaemonReplaced || health.state === 'stopped') {\n    if (verbose && (process.env.OPENCLI_VERBOSE || process.stderr.isTTY)) {\n      process.stderr.write('⏳ Starting daemon...\\n');\n    }\n    daemonLifecycleHooks.spawnDaemonProcess();\n  } else if (verbose && (process.env.OPENCLI_VERBOSE || process.stderr.isTTY)) {\n    process.stderr.write('⏳ Waiting for Chrome/Chromium extension to connect...\\n');\n    process.stderr.write('   Make sure Chrome or Chromium is open and the OpenCLI extension is enabled.\\n');\n  }\n\n  const finalHealth = await waitForBridgeReady(getDaemonHealth, { timeoutMs, contextId, preferredContextId });\n  if (finalHealth.state === 'ready') return finalHealth;\n  throw browserConnectErrorFromHealth(finalHealth, contextId);\n}\n\nfunction browserConnectErrorFromHealth(health: DaemonHealth, contextId?: string): BrowserConnectError {\n  if (health.state === 'profile-required') {\n    return new BrowserConnectError(\n      'Multiple Browser Bridge profiles are connected',\n      'Select one with --profile <name>, OPENCLI_PROFILE=<name>, or opencli profile use <name>.\\n' +\n      'Run opencli profile list to see connected profiles.',\n      'profile-required',\n    );\n  }\n  if (health.state === 'profile-disconnected') {\n    const label = contextId ?? health.status.contextId ?? 'unknown';\n    return new BrowserConnectError(\n      `Browser profile \"${label}\" is not connected`,\n      'Open the matching Chrome profile and make sure the OpenCLI extension is enabled, or choose another profile with opencli profile use <name>.',\n      'profile-disconnected',\n    );","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/browser/daemon-lifecycle.ts#L140-L176","documentation":"ensureBrowserBridgeReady waited for the daemon to become ready (waitForBridgeReady) but the final health state was not 'ready', so it throws BrowserConnectError with code daemon-not-running. This means the OpenCLI daemon started (or was started) but no Chrome/Chromium extension connected within the timeout.","triggerScenarios":"Any Browser Bridge command when finalHealth.state !== 'ready' after waitForBridgeReady's timeoutMs — typically Chrome not running, extension disabled, or extension failing to reach the daemon socket.","commonSituations":"Chrome closed or crashed, OpenCLI extension disabled after a browser update, wrong daemon port/socket, CI environments without a browser, or extension not reloaded after installing the CLI update.","solutions":["Open Chrome/Chromium and ensure the OpenCLI extension is installed and enabled.","Restart the browser (or reload the extension) so it reconnects to the daemon, then retry.","Increase the timeout if the browser/extension takes long to connect on slow machines.","Check the daemon is actually running (start it manually) and that no firewall blocks its local socket."],"exampleFix":"// before\nawait runCommand('browser', 'screenshot', { path: 'x.png' }); // throws daemon-not-running\n// after: ensure readiness with retry\nawait ensureBrowserBridgeReady({ verbose: true, timeoutMs: 30000 });\nawait runCommand('browser', 'screenshot', { path: 'x.png' });","handlingStrategy":"retry","validationCode":"const health = await bridge.health();\nif (health.state !== 'ready') {\n  throw new Error('Browser Bridge not ready: open Chrome and enable the OpenCLI extension');\n}","typeGuard":"function isBridgeReady(health) {\n  return health.state === 'ready';\n}","tryCatchPattern":"try {\n  await runCommand('browser', action, args);\n} catch (e) {\n  if (e.code === 'daemon-not-running') {\n    await waitForBridgeReady(getDaemonHealth, { timeoutMs: 30000, contextId });\n    return runCommand('browser', action, args);\n  }\n  throw e;\n}","preventionTips":["Ensure Chrome/Chromium runs with the OpenCLI extension enabled before invoking bridge commands.","Call health() as a pre-flight check in scripts.","Reload the extension after CLI upgrades so protocol versions match.","Verify the daemon port/socket is not blocked by firewall or sandboxing."],"tags":["daemon","browser-bridge","connectivity"],"backgroundTag":"daemon-not-running","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}