BigPizzaV3/CodexPlusPlus · error
Expected one callback binding
Error message
Expected one callback binding
What it means
transform_binding rewrites a pinned bundled browser-service script by replacing a single known callback-binding anchor string with an instrumented adapter. This error is thrown when the anchor string ANCHOR ('new nf(r,...,cD)') is not found exactly once in the source — zero occurrences means the service file has already been transformed or replaced by a different version, and multiple occurrences mean an unexpected bundle layout. It is a pre-flight invariant check so the blind string replacement never corrupts the file.
Solutions
- Check whether the file was already transformed: if it contains 'cppNativeIdentificationReader', restore the original bundled service file before re-running transform.
- Restore the pristine service file matching ORIGINAL_SHA (reinstall/repair the Codex bundled plugin cache) and retry.
- If a newer upstream bundle legitimately changed, update ANCHOR and the pinned SHA contract in native_browser.rs rather than editing the file by hand.
- Enable debug logging of matches(ANCHOR).count() to confirm whether it is 0 (already transformed/missing) or >1 (bundle drift).
Example fix
// before: blindly re-applying to an already-adapted file
transform(source, control, &contract)?;
// after: detect prior adaptation and restore original first
if text.contains("cppNativeIdentificationReader") {
source = restore_original_service()?; // or skip: already adapted
}
transform(source, control, &contract)?; Defensive patterns
Strategy: validation
Validate before calling
let text = std::fs::read_to_string(&service_path)?;
if text.matches(ANCHOR).count() != 1 {
// already transformed (0) or bundle drift (>1): restore original before applying
restore_original_service(&service_path)?;
} Type guard
fn is_transformable(source: &[u8]) -> bool {
std::str::from_utf8(source)
.map(|t| t.matches(ANCHOR).count() == 1 && !t.contains("cppNativeIdentificationReader"))
.unwrap_or(false)
} Try / catch
match transform(source, control, &contract) {
Ok(patched) => install(patched),
Err(e) if e.to_string().contains("Expected one callback binding") => {
restore_original_service()?; // then retry once
}
Err(e) => return Err(e),
} Prevention
- Always restore the pristine bundled service before re-applying the adaptation
- Check the tool's adaptation status instead of re-running apply blindly
- Pin the Codex plugin version so the bundle cannot drift under the pinned SHA contract
- After upstream updates, verify the service SHA before transforming
When it happens
Trigger: Calling transform/transform_binding on a browser-service.mjs whose text contains 0 or 2+ matches of the anchor: (1) the service hash check passed but the bundle internally differs, (2) transform was run twice so the anchor was already replaced, (3) an upstream bundle update changed the minified identifier 'nf'/'cD' while still matching the pinned SHA file.
Common situations: Applying the opt-in adaptation twice to the same install; a partial/failed previous transform left modified content; upstream Codex shipped a new browser-desktop bundle version that the pinned SHA catalog has not caught up with; hand-edited or vendor-patched service file.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Conflicting adapter
- 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/b02e79ea9a681013.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/native_browser.rs:264
}
})();
if result.is_err() {
let _ = fs::remove_file(&temp);
}
result
}
fn transform(source: &[u8], control: &Path, contract: &RuntimeContract) -> Result<Vec<u8>> {
ensure!(
sha(source) == contract.service_sha,
"Unsupported native browser service hash"
);
transform_binding(source, control)
}
fn transform_binding(source: &[u8], control: &Path) -> Result<Vec<u8>> {
let text = std::str::from_utf8(source)?;
ensure!(
text.matches(ANCHOR).count() == 1,
"Expected one callback binding"
);
ensure!(
!text.contains("cppNativeIdentificationReader"),
"Conflicting adapter"
);
let path = serde_json::to_string(&control.to_str().context("Non-Unicode control path")?)?;
let replacement = format!(
"new nf(r,this.clientApi,()=>ze(this.runtime),this.turnEndedTracker,cppNativeIdentificationReader(this.runtime,cD,ze,{path}))"
);
Ok(format!("{}\n{HELPER}", text.replacen(ANCHOR, &replacement, 1)).into_bytes())
}
fn selected_key(descriptor: &Value, root: &Path) -> Result<String> {
let server = &descriptor["mcpServers"]["cua_repl"];
let node = PathBuf::from(
server["command"]View on GitHub (pinned to b1ed92e5e4)