BigPizzaV3/CodexPlusPlus · error
Conflicting native Node selection
Error message
Conflicting native Node selection
What it means
selected_key cross-checks the descriptor's environment variables against the resolved node path: env NODE_REPL_NODE_PATH must equal the exact node command derived from the server's command field. This error is thrown when the two disagree — the descriptor nominally selects one node binary in 'command' but its environment declares a different one, so the selection is ambiguous/inconsistent and the library refuses to guess which runtime is actually in use.
Solutions
- Set env.NODE_REPL_NODE_PATH to exactly the same absolute path as mcpServers.cua_repl.command (byte-identical, normalized).
- Regenerate the descriptor by reinstalling/repairing the native runtime so command and env are written consistently.
- Search the descriptor for a stale key directory in NODE_REPL_NODE_PATH and update it to the currently selected runtime key.
- If a symlink or case-only difference is intended, normalize both paths before comparison rather than editing one side.
Example fix
// before: command and env disagree
"command": ".../cua_node/rt-2/bin/node.exe"
"env": { "NODE_REPL_NODE_PATH": ".../cua_node/rt-1/bin/node.exe" }
// after: consistent selection
"command": ".../cua_node/rt-2/bin/node.exe"
"env": { "NODE_REPL_NODE_PATH": ".../cua_node/rt-2/bin/node.exe" } Defensive patterns
Strategy: validation
Validate before calling
let cmd = descriptor["mcpServers"]["cua_repl"]["command"].as_str().unwrap();
let env_path = descriptor["mcpServers"]["cua_repl"]["env"]["NODE_REPL_NODE_PATH"].as_str().unwrap_or("");
if Path::new(env_path) != Path::new(cmd) {
eprintln!("command and NODE_REPL_NODE_PATH disagree; fix before discovery");
} Type guard
fn selection_is_consistent(server: &serde_json::Value) -> bool {
let cmd = server["command"].as_str().map(PathBuf::from);
let env = server["env"]["NODE_REPL_NODE_PATH"].as_str().map(PathBuf::from);
cmd.is_some() && cmd == env
} Try / catch
match selected_key(&descriptor, &root) {
Ok(key) => use_runtime(key),
Err(e) if e.to_string().contains("Conflicting native Node selection") => {
fix_env_node_path(&mut descriptor)?; // set env to match command, retry
}
Err(e) => return Err(e),
} Prevention
- Always update command and env.NODE_REPL_NODE_PATH together when changing runtimes
- Use normalized absolute paths (no .., consistent separators) in both fields
- Prefer regenerating the descriptor over manual JSON edits
- After switching runtime keys, re-run the tool's status/validate command before discovery
When it happens
Trigger: discover() -> selected_key() on a descriptor where mcpServers.cua_repl.env.NODE_REPL_NODE_PATH is missing, points to a different runtime key's node.exe, uses a non-canonical spelling (different casing, / vs \, .. segments), or was edited independently of 'command'.
Common situations: Hand-edited config.toml/plugin descriptor changing only one of command/env; partially applied update that rewrote command but not env; two runtimes installed and env left pointing at the old one; path normalization differences after a drive-letter or user-profile change.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Unexpected native runtime layout
- archived lookup task failed
- built-in Dream Skin theme cannot be deleted
- built-in Dream Skin theme is read-only
- cannot terminate Windows process id
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/36451744da781ce5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/native_browser.rs:300
server["command"]
.as_str()
.context("Missing native Node command")?,
);
let relative = node
.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!(View on GitHub (pinned to b1ed92e5e4)