BigPizzaV3/CodexPlusPlus · error · anyhow::Error
No injectable page target found
Error message
No injectable page target found
What it means
pick_page_target selects a Chrome tab to inject into from a /json target list. A target is injectable only when target_type equals page and web_socket_debugger_url is present and non-empty; the picker then prefers the primary Codex page and otherwise falls back to the first injectable page. This error means not a single target in the list was injectable: there were no page-type targets, or every page lacked a WebSocket debugger URL.
Source
Thrown at crates/codex-plus-core/src/cdp.rs:252
}
pub fn pick_page_target(targets: &[CdpTarget]) -> anyhow::Result<CdpTarget> {
let mut first_page = None;
for target in targets
.iter()
.filter(|target| is_injectable_page_target(target))
{
first_page.get_or_insert(target);
if is_primary_codex_page_target(target) {
return Ok(target.clone());
}
}
if let Some(target) = first_page {
return Ok(target.clone());
}
bail!("No injectable page target found")
}
pub fn pick_injectable_codex_page_target(targets: &[CdpTarget]) -> anyhow::Result<CdpTarget> {
let priorities: [fn(&CdpTarget) -> bool; 4] = [
is_exact_codex_app_main_target,
is_primary_codex_app_target,
is_chatgpt_desktop_page_target,
is_supported_codex_page_target,
];
for matches_priority in priorities {
if let Some(target) = targets
.iter()
.find(|target| is_injectable_page_target(target) && matches_priority(target))
{
return Ok(target.clone());
}
}
bail!("No injectable Codex page target found")View on GitHub (pinned to f2074595a2)
Solutions
- Open or keep at least one regular tab in the browser being debugged
- Relaunch the browser with --remote-debugging-port=PORT (not --remote-debugging-pipe) so pages expose webSocketDebuggerUrl
- Verify the list came from http://127.0.0.1:PORT/json and includes targets of type page
- Close other DevTools clients holding sessions on the pages, then re-query
Example fix
// before: selection on a possibly empty list let target = pick_page_target(&targets)?; // after: ensure an injectable page exists first ensure_browser_has_open_page(&client, debug_port).await?; let targets = query_targets_url(&client, &list_url, debug_port).await?; let target = pick_page_target(&targets)?;
Defensive patterns
Strategy: validation
Validate before calling
let injectable = targets.iter().any(|t| t.target_type == "page" && t.web_socket_debugger_url.as_deref().is_some_and(|u| !u.is_empty()));
if !injectable {
// open a tab or relaunch with --remote-debugging-port, then re-query
} Type guard
fn has_injectable_page_target(targets: &[CdpTarget]) -> bool {
targets.iter().any(|t| t.target_type == "page" && t.web_socket_debugger_url.as_deref().is_some_and(|u| !u.is_empty()))
} Try / catch
if let Err(e) = pick_page_target(&targets) {
if e.to_string().contains("No injectable page target") {
open_or_relaunch_browser().await?;
let targets = requery_targets(debug_port).await?;
return pick_page_target(&targets);
}
return Err(e);
} Prevention
- Check the target list for a page entry before picking
- Prefer --remote-debugging-port over pipe mode
- Keep at least one ordinary tab open while injecting
When it happens
Trigger: Passing a CdpTarget list where all targets are service_worker, background_page, iframe or other non-page types; querying /json when every tab is closed; the browser was launched with --remote-debugging-pipe instead of a port so pages expose no webSocketDebuggerUrl.
Common situations: Headless Chrome started with pipe-based debugging; all tabs closed by selection time; target list fetched from /json/version or a non-Chromium endpoint that returns no targets array; DevTools already holding the only debug session on the page.
Related errors
- CDP WebSocket port {port} does not match debug port {expecte
- No injectable Codex page target found
- Page.captureScreenshot returned invalid PNG data
- periodic Runtime.evaluate reported unavailable capability
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@f2074595a2 (2026-08-23).
Data as JSON: /api/errors/55ceaa939c61c8d7.
Report an issue: GitHub.