BigPizzaV3/CodexPlusPlus · error

Conflicting native worker selection

Error message

Conflicting native worker selection

What it means

This error is thrown by selected_key while validating an .mcp.json plugin descriptor for the native browser runtime. The descriptor's CUA_REPL_NODE_REPL_PATH env var must point at the cached worker binary <runtime_root>/<key>/bin/node_repl.exe that corresponds to the runtime key derived from the command path. If it names a different node_repl.exe (another runtime key, an absolute system path, or a stale entry), the descriptor is internally inconsistent, so discovery refuses to select it.

Solutions

  1. Delete the offending plugin descriptor directory under codex_home/plugins/cache/openai-bundled/unified-computer-use so only consistent descriptors remain
  2. Reinstall/refresh the unified-computer-use plugin so the .mcp.json is regenerated with a matching CUA_REPL_NODE_REPL_PATH
  3. Edit the .mcp.json so CUA_REPL_NODE_REPL_PATH exactly equals <runtime_root>/<key>/bin/node_repl.exe where <key> is the first path component under runtime_root in the command field

Example fix

// before (.mcp.json)
"env": { "CUA_REPL_NODE_REPL_PATH": "/usr/local/bin/node_repl.exe" }
// after
"env": { "CUA_REPL_NODE_REPL_PATH": "/home/user/.codex/browser-runtime/<key>/bin/node_repl.exe" }
Defensive patterns

Strategy: validation

Validate before calling

let expected_worker = runtime_root.join(key).join("bin/node_repl.exe");
if descriptor["mcpServers"]["cua_repl"]["env"]["CUA_REPL_NODE_REPL_PATH"].as_str() != Some(expected_worker.to_str().unwrap()) {
    eprintln!("descriptor CUA_REPL_NODE_REPL_PATH does not match cached worker for key {key}");
}

Type guard

fn worker_path_matches(env: &Value, root: &Path, key: &str) -> bool {
    env["CUA_REPL_NODE_REPL_PATH"].as_str()
        .map(|p| Path::new(p) == root.join(key).join("bin/node_repl.exe"))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: selected_key (called from discover during reconcile_locked/observation) parses a .mcp.json whose mcpServers.cua_repl.env.CUA_REPL_NODE_REPL_PATH resolves to a path other than runtime_root/<key>/bin/node_repl.exe — e.g. the env var was hand-edited, points to a previous runtime version, or to a globally installed node_repl.exe.

Common situations: Users who manually edited the plugin's .mcp.json; leftover descriptors from an older runtime version after an upgrade; a plugin generated by another tool that sets CUA_REPL_NODE_REPL_PATH to a system Node; copied config files between machines with different runtime caches.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/codex-plus-core/src/native_browser.rs:305

        .strip_prefix(root)
        .context("Native Node is outside the runtime cache")?;
    let parts: Vec<_> = relative.components().collect();
    ensure!(parts.len() == 3, "Unexpected native runtime layout");
    let key = parts[0]
        .as_os_str()
        .to_str()
        .context("Invalid runtime key")?;
    ensure!(
        key_valid(key) && relative == Path::new(key).join("bin/node.exe"),
        "Unexpected native runtime layout"
    );
    let env = &server["env"];
    ensure!(
        env["NODE_REPL_NODE_PATH"].as_str().map(Path::new) == Some(node.as_path()),
        "Conflicting native Node selection"
    );
    let worker = root.join(key).join("bin/node_repl.exe");
    ensure!(
        env["CUA_REPL_NODE_REPL_PATH"].as_str().map(Path::new) == Some(worker.as_path()),
        "Conflicting native worker selection"
    );
    let services: Value = serde_json::from_str(
        env["NODE_REPL_TRUSTED_SERVICES"]
            .as_str()
            .context("Missing native service map")?,
    )?;
    ensure!(
        services["browser"] == "@oai/browser-desktop/service",
        "Original browser service is not selected"
    );
    ensure!(
        env["CUA_REPL_ENABLED_SURFACES"].as_str() == Some("browser"),
        "Unsupported native surface selection"
    );
    let args = server["args"]
        .as_array()

View on GitHub (pinned to b1ed92e5e4)