BigPizzaV3/CodexPlusPlus · error · anyhow::Error

CDP command id failed

Error message

CDP command {method} id {message_id} failed: {error}

What it means

command_result inspects a CDP response and, when it contains an "error" object, converts it into a Rust error embedding the method name, message id, and the serialized error payload. This is the standard surface for CDP-level protocol errors (unknown method, invalid parameters, internal browser errors) — the command was delivered and answered, but with a failure result.

Solutions

  1. Read the embedded error JSON in the message — CDP errors include code and message explaining the cause
  2. Ensure required domains are enabled first (e.g. Page.enable before Page commands)
  3. Align CDP method/params with the target browser's supported protocol version
  4. Re-issue the command after navigation/reload when the error references a destroyed context

Example fix

// before
session.send_command(id, "Page.captureScreenshot", params).await?;
// after
session.send_command(id, "Page.enable", json!({})).await?;
session.send_command(id, "Page.captureScreenshot", params).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// check domain support before calling (protocol version sniff)
let version = send_cdp_command(&ws, "Browser.getVersion", json!({})).await?;
eprintln!("target: {}", version["result"]["product"]);

Type guard

fn is_cdp_error(response: &serde_json::Value) -> bool {
    response.get("error").is_some()
}

Try / catch

match session.send_command(id, method, params).await {
    Err(e) if e.to_string().contains("failed:") => {
        // e contains the CDP error object; log method+id and adjust params or enable the domain
        eprintln!("CDP error on {method}: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Any send_command whose response carries an "error" field: calling an unsupported CDP method on the browser version, invalid params, or browser-side errors (e.g. 'Runtime.evaluate' on a destroyed execution context, Page domain not enabled).

Common situations: Version drift between the bridge and the target Chromium dropping/renaming CDP methods; sending Page commands before Page.enable; referencing a stale execution context after navigation; typos in method or parameter names.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/fa40223cbb842fef. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/bridge.rs:953

            }
            Err(error) => {
                let _ = crate::diagnostic_log::append_diagnostic_log(
                    "bridge.reject_failed",
                    json!({
                        "request_id": request_id,
                        "message_id": message_id,
                        "error": error.to_string()
                    }),
                );
            }
        }
        sent.map(|_| ())
    }
}

fn command_result(response: Value, method: &str, message_id: u64) -> anyhow::Result<Value> {
    if let Some(error) = response.get("error") {
        bail!("CDP command {method} id {message_id} failed: {error}");
    }
    Ok(response)
}

fn ensure_runtime_evaluate_succeeded(response: Value) -> anyhow::Result<Value> {
    if let Some(exception) = response
        .get("result")
        .and_then(|result| result.get("exceptionDetails"))
    {
        bail!("Runtime.evaluate raised an exception: {exception}");
    }
    Ok(response)
}

fn runtime_evaluate_result_is_false(response: &Value) -> bool {
    response
        .get("result")
        .and_then(|result| result.get("result"))

View on GitHub (pinned to b1ed92e5e4)