BigPizzaV3/CodexPlusPlus · error

Runtime changed outside Codex++

Error message

Runtime changed outside Codex++

What it means

After restoring the journaled original, prepare() asserts that the service file's SHA matches the contract's expected service_sha. If it doesn't, the runtime service file was changed by something other than Codex++'s patch/restore cycle (external modification or version drift), and Codex++ refuses to patch on top of an unknown base to keep its backup/restore guarantees intact.

Solutions

  1. Refresh the runtime: reinstall/update the plugin so the on-disk service matches the current contract's service_sha, then re-run reconcile
  2. If Codex++ is older than the runtime, upgrade Codex++ so its contract ships the new service_sha
  3. Restore the pristine service file from the plugin package (never hand-edit) and retry
Defensive patterns

Strategy: validation

Validate before calling

let current = read_regular(&target, MAX_SERVICE)?;
if sha(&current) != contract.service_sha {
    eprintln!("service file does not match contract (sha {:?}); reinstall runtime before patching", sha(&current));
}

Try / catch

if let Err(e) = prepare(&paths, &key, &contract) {
    if e.to_string().contains("Runtime changed outside Codex++") {
        restore_pristine_service_from_plugin_package(&runtime)?; // or reinstall plugin
        prepare(&paths, &key, &contract)?;
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: prepare() with a journal: current (after possible restore) hashes to something != contract.service_sha — e.g. the plugin updated browser-desktop between Codex++ runs so the original file no longer matches the contract, or a user/tool edited the service bundle.

Common situations: Browser/plugin auto-update changing the bundled service between Codex++ sessions; manual hot-fixes inside node_modules; partial upgrade leaving a mixed-version service file.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/b5cf7397ed61dc39. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/native_browser.rs:404

    if journal_path.exists() {
        let (journal, original, recorded_candidate) = recovery_material(paths, key, contract)?;
        let candidate = transform(&original, &control, contract)?;
        if current == recorded_candidate {
            if candidate == recorded_candidate {
                return Ok(());
            }
            // Restore before upgrading the journal, so either journal can recover a crash.
            ensure!(
                read_regular(&target, MAX_SERVICE)? == current,
                "Concurrent adapter upgrade"
            );
            let modified = UNIX_EPOCH
                .checked_add(Duration::new(journal.modified_secs, journal.modified_nanos))
                .context("Invalid recovery timestamp")?;
            atomic_write_with_modified(&target, &original, Some(modified))?;
            current = original;
        }
        ensure!(
            sha(&current) == contract.service_sha,
            "Runtime changed outside Codex++"
        );
    }
    {
        let candidate = transform(&current, &control, contract)?;
        if backup.exists() {
            ensure!(
                read_regular(&backup, MAX_SERVICE)? == current,
                "Unjournaled backup conflict"
            );
        } else {
            write_new(&backup, &current)?;
        }
        let candidate_path = backup_dir.join(format!("candidate-{}.mjs", sha(&candidate)));
        if candidate_path.exists() {
            ensure!(
                read_regular(&candidate_path, MAX_SERVICE)? == candidate,

View on GitHub (pinned to b1ed92e5e4)