{"record":{"id":"e0bb1eac2ba518e5","repo":"BigPizzaV3/CodexPlusPlus","slug":"conflicting-adapter","errorCode":null,"errorMessage":"Conflicting adapter","messagePattern":"Conflicting adapter","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/native_browser.rs","lineNumber":268,"sourceCode":"    }\n    result\n}\n\nfn transform(source: &[u8], control: &Path, contract: &RuntimeContract) -> Result<Vec<u8>> {\n    ensure!(\n        sha(source) == contract.service_sha,\n        \"Unsupported native browser service hash\"\n    );\n    transform_binding(source, control)\n}\n\nfn transform_binding(source: &[u8], control: &Path) -> Result<Vec<u8>> {\n    let text = std::str::from_utf8(source)?;\n    ensure!(\n        text.matches(ANCHOR).count() == 1,\n        \"Expected one callback binding\"\n    );\n    ensure!(\n        !text.contains(\"cppNativeIdentificationReader\"),\n        \"Conflicting adapter\"\n    );\n    let path = serde_json::to_string(&control.to_str().context(\"Non-Unicode control path\")?)?;\n    let replacement = format!(\n        \"new nf(r,this.clientApi,()=>ze(this.runtime),this.turnEndedTracker,cppNativeIdentificationReader(this.runtime,cD,ze,{path}))\"\n    );\n    Ok(format!(\"{}\\n{HELPER}\", text.replacen(ANCHOR, &replacement, 1)).into_bytes())\n}\n\nfn selected_key(descriptor: &Value, root: &Path) -> Result<String> {\n    let server = &descriptor[\"mcpServers\"][\"cua_repl\"];\n    let node = PathBuf::from(\n        server[\"command\"]\n            .as_str()\n            .context(\"Missing native Node command\")?,\n    );\n    let relative = node","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/native_browser.rs#L250-L286","documentation":"After confirming exactly one anchor binding, transform_binding refuses to run when the source already contains the string 'cppNativeIdentificationReader' — i.e. this very adapter (or a competing one) has already been injected. The check is idempotency/conflict protection: double-injection would nest adapters and break the identification callback.","triggerScenarios":"Running transform on a service file that was previously adapted by this tool (or a conflicting adapter using the same helper symbol): repeated 'apply' invocations without restoring the original, a transform that succeeded but whose atomic file move later failed leaving adapted content in place, or another patching tool injecting the same reader name.","commonSituations":"Users toggling the opt-in native-browser identification feature on twice; switching profile/apply flows that each run transform; leftover adapted file after a crash mid-apply; coexisting community patches of the same bundle.","solutions":["Skip transform — the file is already adapted; the current invocation is a no-op re-apply.","Restore the original service file (SHA 3e6fd4a8...) from the pinned bundle, then re-run transform once.","If another tool injected a conflicting adapter, uninstall/disable it before using this feature.","Verify via the tool's status command whether the adaptation is already active before calling apply."],"exampleFix":"// before: unconditional apply loop\napply_native_browser(paths)?; // second call -> Conflicting adapter\n// after: idempotent guard\nif is_already_adapted(paths)? { return Ok(()); }\napply_native_browser(paths)?;","handlingStrategy":"validation","validationCode":"let text = std::fs::read_to_string(&service_path)?;\nif text.contains(\"cppNativeIdentificationReader\") {\n    return Ok(()); // already adapted; skip transform entirely\n}","typeGuard":"fn is_already_adapted(source: &[u8]) -> bool {\n    std::str::from_utf8(source)\n        .map(|t| t.contains(\"cppNativeIdentificationReader\"))\n        .unwrap_or(false)\n}","tryCatchPattern":"match transform_binding(source, control) {\n    Ok(patched) => install(patched),\n    Err(e) if e.to_string().contains(\"Conflicting adapter\") => Ok(()), // idempotent no-op\n    Err(e) => return Err(e),\n}","preventionTips":["Make apply flows idempotent: check for the adapter marker before transforming","Restore the original file before toggling the feature off/on","Avoid running multiple tools that patch the same bundled service file","Track apply state in the tool's state dir instead of inferring from file contents"],"tags":["rust","transform","idempotency","conflicting-config-options"],"backgroundTag":"conflicting-config-options","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}