{"record":{"id":"a40cbaf2da9d3d01","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-injection-failed","errorCode":null,"errorMessage":"Codex injection failed","messagePattern":"Codex injection failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/codex-plus-launcher/src/main.rs","lineNumber":1026,"sourceCode":"\nasync fn inject_with_context(\n    debug_port: u16,\n    helper_port: u16,\n    ctx: BridgeContext,\n    runtime: Arc<LauncherRuntimeService>,\n) -> anyhow::Result<()> {\n    let mut last_error = None;\n    for _ in 0..20 {\n        match try_inject_with_context(debug_port, helper_port, ctx.clone(), runtime.clone()).await {\n            Ok(()) => return Ok(()),\n            Err(error) => {\n                last_error = Some(error);\n                tokio::time::sleep(std::time::Duration::from_millis(500)).await;\n            }\n        }\n    }\n\n    Err(last_error.unwrap_or_else(|| anyhow::anyhow!(\"Codex injection failed\")))\n}\n\nfn remote_control_recovery_is_superseded_by_openai(\n    settings: &codex_plus_core::settings::BackendSettings,\n    request: &codex_plus_core::remote_control_recovery::PendingRemoteControlRecovery,\n) -> bool {\n    settings.active_relay_id == request.profile_id\n        && settings.active_relay_session_provider()\n            == codex_plus_core::settings::RelaySessionProvider::Openai\n}\n\nasync fn try_inject_with_context(\n    debug_port: u16,\n    helper_port: u16,\n    ctx: BridgeContext,\n    runtime: Arc<LauncherRuntimeService>,\n) -> anyhow::Result<()> {\n    let targets = codex_plus_core::cdp::list_targets(debug_port).await?;","sourceCodeStart":1008,"sourceCodeEnd":1044,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/apps/codex-plus-launcher/src/main.rs#L1008-L1044","documentation":"The launcher retries injecting the Codex helper script into the Codex browser page over CDP in a loop; each failed attempt records the error in last_error and sleeps 500ms. When the loop exits without a successful injection, it returns the last recorded error — or this generic message via unwrap_or_else when last_error is None, i.e. the loop body never recorded any error at all. It is a fallback sentinel indicating injection never got off the ground rather than a specific failure.","triggerScenarios":"The injection retry loop in the launcher finished all attempts without success and last_error was None — meaning no injection attempt ever executed or stored an error (e.g. the loop never entered its attempt branch), so unwrap_or_else produced this placeholder message instead of a concrete cause.","commonSituations":"Browser not launched with the expected CDP debug port, injected page never became available within the retry window, browser closed mid-retry, or a refactor left the loop unable to reach the injection call so last_error stays None.","solutions":["Verify the browser is running with the CDP debug port enabled and that the port matches the launcher configuration","Check launcher logs immediately before this error for earlier concrete per-attempt errors (those are the real cause)","Increase the retry window/retries if the Codex page loads slowly","Ensure the loop always assigns last_error on failure so future errors carry a concrete cause instead of this sentinel"],"exampleFix":"// before\nErr(last_error.unwrap_or_else(|| anyhow::anyhow!(\"Codex injection failed\")))\n// after\nErr(last_error.unwrap_or_else(|| {\n    anyhow::anyhow!(\"Codex injection failed: no attempt completed within the retry window (check CDP debug port and browser state)\")\n}))","handlingStrategy":"retry","validationCode":"// 检查 CDP 调试端口可达后再触发注入\nlet targets = reqwest::get(format!(\"http://127.0.0.1:{debug_port}/json\")).await?;\nif !targets.status().is_success() {\n    anyhow::bail!(\"CDP debug port {debug_port} not responding; browser not started with remote debugging?\");\n}","typeGuard":null,"tryCatchPattern":"match launcher.inject_codex().await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"Codex injection failed\") => {\n        eprintln!(\"injection never started; check CDP port and browser state: {e}\");\n        // 手动重启带调试端口的浏览器后重试\n    }\n    Err(e) => eprintln!(\"injection attempt error: {e}\"),\n}","preventionTips":["Always launch the browser with the CDP remote debugging port the launcher expects","Wait for the Codex page to fully load before triggering injection","Check per-attempt logs — this sentinel error means a concrete earlier error was (or wasn't) recorded","Keep last_error assignment unconditional in the retry loop so real causes surface"],"tags":["rust","cdp","injection","retry-loop","browser-automation"],"backgroundTag":"connection-refused","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}