BigPizzaV3/CodexPlusPlus · error
selected CDP target has no websocket URL
Error message
selected CDP target has no websocket URL
What it means
After listing CDP targets and picking an injectable Codex page target, the launcher reads target.web_socket_debugger_url to attach a WebSocket for script injection. This error is thrown with ok_or_else when that optional field is None — the selected target exists but the DevTools handshake URL the debugger would connect to is absent, so injection cannot proceed.
Solutions
- Re-list CDP targets and retry until the chosen page exposes webSocketDebuggerUrl (page fully loaded)
- Tighten pick_injectable_codex_page_target to only select targets guaranteed to have a WS URL
- Confirm the browser version supports webSocketDebuggerUrl on /json targets
- Navigate the Codex page manually first, then rerun injection
Defensive patterns
Strategy: validation
Validate before calling
fn target_has_ws_url(t: &codex_plus_core::cdp::Target) -> bool {
t.web_socket_debugger_url.as_deref().map_or(false, |u| u.starts_with("ws"))
}
// 注入前:只挑选带 WS URL 的可注入 target
let target = targets.iter().find(|t| target_has_ws_url(t)); Type guard
fn has_websocket_url(target: &Target) -> Option<&str> {
target.web_socket_debugger_url.as_deref().filter(|u| !u.is_empty())
} Prevention
- Re-list /json targets and pick again if the chosen page lacks webSocketDebuggerUrl (page still loading)
- Filter targets to fully-loaded page targets before injection
- Pin to browser versions known to always emit webSocketDebuggerUrl for page targets
- Log the full target list on failure to spot which target kinds lack WS URLs
When it happens
Trigger: codex_plus_core::cdp::pick_injectable_codex_page_target returned a target whose web_socket_debugger_url field is None — e.g. the /json target list contained an entry without a webSocketDebuggerUrl (about:blank, still-loading page, or a non-page target that slipped through the picker).
Common situations: Attaching to a browser page before it finished loading (DevTools WS URL not yet assigned), targeting browsers that omit webSocketDebuggerUrl for certain targets, or a picker filter that matches more target kinds than the CDP implementation supports.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Codex injection failed
- CDP websocket closed before response for
- CDP WebSocket URL has no host
- CDP WebSocket URL must include an explicit port
- CDP WebSocket URL must include an explicit port
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/13e4e1ef1582dde6.
Report an issue: GitHub.
Appendix: source
Thrown at apps/codex-plus-launcher/src/main.rs:1049
request: &codex_plus_core::remote_control_recovery::PendingRemoteControlRecovery,
) -> bool {
settings.active_relay_id == request.profile_id
&& settings.active_relay_session_provider()
== codex_plus_core::settings::RelaySessionProvider::Openai
}
async fn try_inject_with_context(
debug_port: u16,
helper_port: u16,
ctx: BridgeContext,
runtime: Arc<LauncherRuntimeService>,
) -> anyhow::Result<()> {
let targets = codex_plus_core::cdp::list_targets(debug_port).await?;
let target = codex_plus_core::cdp::pick_injectable_codex_page_target(&targets)?;
let websocket_url = target
.web_socket_debugger_url
.as_deref()
.ok_or_else(|| anyhow::anyhow!("selected CDP target has no websocket URL"))?;
runtime.set_websocket_url(websocket_url);
let settings = codex_plus_core::settings::SettingsStore::default()
.load()
.unwrap_or_default();
let script = codex_plus_core::assets::injection_script_with_settings(helper_port, &settings);
let user_bundle = runtime
.user_scripts
.build_enabled_bundle()
.unwrap_or_default();
let new_document_scripts = if user_bundle.is_empty() {
vec![script]
} else {
vec![script, user_bundle]
};
codex_plus_core::bridge::install_bridge(
websocket_url,
codex_plus_core::bridge::BRIDGE_BINDING_NAME,
Arc::new(move |path, payload| {View on GitHub (pinned to b1ed92e5e4)