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

  1. Check whether the file was already transformed: if it contains 'cppNativeIdentificationReader', restore the original bundled service file before re-running transform.
  2. Restore the pristine service file matching ORIGINAL_SHA (reinstall/repair the Codex bundled plugin cache) and retry.
  3. 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.
  4. 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

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


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)