{"record":{"id":"0b1bae3d101762a7","repo":"can1357/oh-my-pi","slug":"failed-to-attach-to-path-basename-exe-on-cdp","errorCode":null,"errorMessage":"Failed to attach to ${path.basename(exe)} on ${cdpUrl}: ${(err as Error).message}","messagePattern":"Failed to attach to (.+?) on (.+?): (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/registry.ts","lineNumber":290,"sourceCode":"\t\tif (killed > 0) logger.debug(\"Killed existing instances before attach\", { exe, killed });\n\t\tconst port = await findFreeCdpPort();\n\t\tconst launchArgs = [...(opts.appArgs ?? []), `--remote-debugging-port=${port}`];\n\t\tconst child = Bun.spawn([exe, ...launchArgs], {\n\t\t\tstdout: \"ignore\",\n\t\t\tstderr: \"ignore\",\n\t\t\tstdin: \"ignore\",\n\t\t});\n\t\tchild.unref();\n\t\tsubprocess = child;\n\t\tpid = child.pid;\n\t\tcdpUrl = `http://127.0.0.1:${port}`;\n\t\ttry {\n\t\t\tawait waitForCdp(cdpUrl, 30_000, opts.signal);\n\t\t} catch (err) {\n\t\t\tawait gracefulKillTreeOnce(child.pid).catch(() => undefined);\n\t\t\tif (err instanceof ToolAbortError) throw err;\n\t\t\tif (err instanceof Error && err.name === \"AbortError\") throw err;\n\t\t\tthrow new ToolError(`Failed to attach to ${path.basename(exe)} on ${cdpUrl}: ${(err as Error).message}`);\n\t\t}\n\t}\n\n\tconst puppeteer = await loadPuppeteer();\n\tlet browser: Browser;\n\ttry {\n\t\tbrowser = await puppeteer.connect({\n\t\t\tbrowserURL: cdpUrl,\n\t\t\tdefaultViewport: null,\n\t\t\tprotocolTimeout: BROWSER_PROTOCOL_TIMEOUT_MS,\n\t\t});\n\t} catch (err) {\n\t\tif (subprocess) await gracefulKillTreeOnce(subprocess.pid);\n\t\tthrow new ToolError(`Connected to ${cdpUrl} but puppeteer.connect failed: ${(err as Error).message}`);\n\t}\n\treturn {\n\t\tkey: browserKey(kind),\n\t\tkind,","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/registry.ts#L272-L308","documentation":"After launching the browser subprocess with remote debugging, openBrowserHandle waits up to 30 seconds for the CDP endpoint to come up. If waitForCdp fails (browser exited, crashed, never opened the port, or the signal aborted) it kills the child process tree and rethrows as ToolError, wrapping the underlying waitForCdp message plus the executable name and CDP URL.","triggerScenarios":"Launching a browser binary that crashes on startup (incompatible flags, corrupted profile, sandbox issues in containers); a binary that doesn't honor --remote-debugging-port; port conflicts; abort signal firing during the 30s attach wait.","commonSituations":"Running Chrome/Chromium in Docker without --no-sandbox equivalents the tool expects; old browser versions rejecting new flags; headless environments lacking display libraries; the chosen debug port already in use by another process.","solutions":["Run the executable manually with the same flags to see why it exits (crash logs, missing --no-sandbox in root/containers)","Try a different remote debugging port (the port may be occupied by a stale process)","Update or reinstall the browser binary; verify it supports the debugging flags used","Check the abort signal isn't cancelling during startup if errors mention AbortError"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight: can this binary even start? (spawn it with --version)\nconst probe = Bun.spawnSync([exe, \"--version\"], { stdout: \"pipe\", stderr: \"pipe\" });\nif (probe.exitCode !== 0) console.error(\"Browser binary fails to launch:\", probe.stderr.toString());","typeGuard":null,"tryCatchPattern":"try {\n  const handle = await openBrowserHandle(kind, { signal });\n} catch (err) {\n  if (err instanceof ToolError && err.message.startsWith(\"Failed to attach to\")) {\n    // retry once after killing stale processes on the debug port\n  }\n  throw err;\n}","preventionTips":["Verify the browser binary launches manually with the same flags before automating it","In containers/root, ensure sandbox flags (e.g. --no-sandbox equivalents) are handled","Pick a free remote-debugging port; clean up stale debug ports between runs","Keep browser binaries updated; ancient versions may reject current CDP flags"],"tags":["browser","cdp","process","timeout","launch-failure"],"backgroundTag":"browser-launch-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}