{"record":{"id":"8242f9e1944e8386","repo":"BigPizzaV3/CodexPlusPlus","slug":"periodic-runtime-evaluate-reported-unavailable-cap","errorCode":null,"errorMessage":"periodic Runtime.evaluate reported unavailable capability","messagePattern":"periodic Runtime\\.evaluate reported unavailable capability","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/codex-plus-core/src/bridge.rs","lineNumber":167,"sourceCode":"{\n    let socket = connect_cdp_websocket(websocket_url).await?;\n    let mut session = CdpSession::new(socket);\n    let mut interval = tokio::time::interval(period);\n    loop {\n        interval.tick().await;\n        let Some(expression) = next_expression()? else {\n            return Ok(());\n        };\n        let response = session\n            .send_command(\n                next_message_id(),\n                \"Runtime.evaluate\",\n                runtime_evaluate_params(&expression),\n            )\n            .await?;\n        let response = ensure_runtime_evaluate_succeeded(response)?;\n        if runtime_evaluate_result_is_false(&response) {\n            bail!(\"periodic Runtime.evaluate reported unavailable capability\");\n        }\n    }\n}\n\npub async fn add_script_to_new_documents(\n    websocket_url: &str,\n    script: &str,\n) -> anyhow::Result<Value> {\n    let socket = connect_cdp_websocket(websocket_url).await?;\n    let mut session = CdpSession::new(socket);\n    session\n        .send_command(\n            1,\n            \"Page.addScriptToEvaluateOnNewDocument\",\n            json!({ \"source\": script }),\n        )\n        .await\n}","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/fb3ebd9a82383aedd8d098aa9ae3aef9426d13a4/crates/codex-plus-core/src/bridge.rs#L149-L185","documentation":"run_periodic_evaluations polls the page on an interval by evaluating a capability-probe expression via Runtime.evaluate. If the expression evaluates to literal false (runtime_evaluate_result_is_false), the loop bails: the page itself reports that the required capability is absent, so periodic work stops by design.","triggerScenarios":"The probe expression (typically checking for a window API the injected feature depends on) returns false: an older app build without the API, the page navigated away or not yet finished loading its globals, or evaluation landing in a context where the global is missing.","commonSituations":"The desktop app version is older than the manager expects; timing - the first evaluation fires before page load completes; the capability is disabled in the target build.","solutions":["Open the target page devtools and evaluate the same probe expression manually to see which capability is missing","Update the desktop app to a version that ships the expected capability","Confirm the websocket is attached to the correct page target (see pick_injectable_codex_page_target)","Delay the first evaluation or tolerate a few consecutive false results before giving up"],"exampleFix":"// before - the first false result kills the loop\nif runtime_evaluate_result_is_false(&response) {\n    bail!(\"periodic Runtime.evaluate reported unavailable capability\");\n}\n\n// after - tolerate transient false, stop only when stable\nlet mut false_streak = 0usize;\nif runtime_evaluate_result_is_false(&response) {\n    false_streak += 1;\n    if false_streak >= 3 {\n        bail!(\"periodic Runtime.evaluate reported unavailable capability\");\n    }\n    continue;\n}\nfalse_streak = 0;","handlingStrategy":"fallback","validationCode":"// One-shot capability probe before starting the periodic loop\nlet response = session.send_command(next_message_id(), \"Runtime.evaluate\",\n    runtime_evaluate_params(&probe_expression)).await?;\nif runtime_evaluate_result_is_false(&ensure_runtime_evaluate_succeeded(response)?) {\n    return Ok(()); // capability absent: degrade silently instead of running the loop\n}\nrun_periodic_evaluations(&ws_url, period, next_expression).await","typeGuard":null,"tryCatchPattern":"if let Err(e) = run_periodic_evaluations(&ws_url, period, next_expr).await {\n    if e.to_string().contains(\"unavailable capability\") {\n        tracing::info!(\"skin capability absent; periodic evaluation disabled\");\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Probe capabilities once before enabling features that depend on them","Version-gate features against the target app version","Re-probe on page navigation events rather than relying on a fixed interval"],"tags":["cdp","runtime-evaluate","feature-detection","polling"],"backgroundTag":"feature-detection-failed","analyzedSha":"fb3ebd9a82383aedd8d098aa9ae3aef9426d13a4","analyzedAt":"2026-08-17T11:35:12.031Z","contentChangedAt":"2026-08-17T11:35:12.031Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}