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
- Delete the offending plugin descriptor directory under codex_home/plugins/cache/openai-bundled/unified-computer-use so only consistent descriptors remain
- Reinstall/refresh the unified-computer-use plugin so the .mcp.json is regenerated with a matching CUA_REPL_NODE_REPL_PATH
- 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
- Never hand-edit .mcp.json env paths; let the plugin generate them
- After runtime upgrades, verify CUA_REPL_NODE_REPL_PATH points into the new runtime key directory
- Keep one plugin version installed to avoid mixed-key descriptors
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
- Original browser service is not selected
- Unsupported native entry point
- Ambiguous runtime selection; no cache was modified
- Unsupported native surface selection
- 官方混合 API 不应在 auth.json 中保存 OPENAI_API_KEY。请清理此供应商的…
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)