BigPizzaV3/CodexPlusPlus · error

Native browser compatibility is still enabled

Error message

Native browser compatibility is still enabled

What it means

verify_restored_state confirms that after the monitor has been shut down and compatibility disabled, the feature is really off. It reads state_root/control.json and requires schema==1 and requireIdentification==false; if control.json still says requireIdentification==true, native browser compatibility is still flagged as enabled and this error is thrown. This is a fail-closed post-condition check guarding against a shutdown path that skipped writing the disabled control marker.

Solutions

  1. Run reconcile(&paths, false) to explicitly disable: it rewrites control.json to {"schema":1,"requireIdentification":false} and restores the service, then restart the monitor if needed.
  2. Delete or fix the stale control.json in state_root (or restore the correct disabled marker) if it was hand-edited or came from an old backup, then re-verify.
  3. Ensure only one launcher/monitor instance owns the state (check monitor.lock/owner.lock) so a concurrent process is not re-enabling the flag during shutdown.

Example fix

// before: shutdown verification sees stale enabled control
let _ = monitor.stop().await; // verify_restored_state -> "still enabled"

// after: explicitly disable and flush state before stopping the monitor
reconcile(&paths, false)?;
monitor.stop().await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check the control marker before shutting down the monitor
fn control_is_disabled(paths: &BrowserPaths) -> std::io::Result<bool> {
    let p = paths.state_root.join("control.json");
    if !p.exists() { return Ok(true); }
    let v: serde_json::Value = serde_json::from_slice(&std::fs::read(p)?)?;
    Ok(v["schema"] == 1 && v["requireIdentification"] == false)
}

Try / catch

if let Err(e) = monitor.stop_and_verify().await {
    if e.to_string().contains("still enabled") {
        // explicitly disable (rewrites control.json) then re-verify
        reconcile(&paths, false)?;
    }
}

Prevention

When it happens

Trigger: wait_for_monitor_shutdown_at -> verify_restored_state while state_root/control.json exists with requireIdentification==true (or a malformed value that is not false). Happens when monitor shutdown occurred without reconcile_locked completing its disable branch, when a concurrent reconcile re-enabled the feature, or when control.json was hand-edited / written by an older version with a different schema.

Common situations: Killing or crashing the monitor before it wrote the disabled control.json; another launcher instance re-preparing the feature while shutdown verification runs; manually restoring an old state_root snapshot that still has the enabled control file; schema drift after a version upgrade.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

        schema: 1,
        generation: generation.into(),
        state: state.into(),
    })?;
    file.seek(SeekFrom::Start(0))?;
    file.set_len(0)?;
    file.write_all(&bytes)?;
    file.sync_all()?;
    Ok(())
}

fn verify_restored_state(paths: &BrowserPaths) -> Result<()> {
    if !paths.state_root.exists() {
        return Ok(());
    }
    let control = paths.state_root.join("control.json");
    if control.exists() {
        let value: Value = serde_json::from_slice(&read_regular(&control, 1024)?)?;
        ensure!(
            value["schema"] == 1 && value["requireIdentification"] == false,
            "Native browser compatibility is still enabled"
        );
    }
    for entry in fs::read_dir(&paths.state_root)? {
        let key = entry?.file_name().to_string_lossy().to_string();
        if !key_valid(&key) || !paths.state_root.join(&key).join("journal.json").exists() {
            continue;
        }
        let target = paths.runtime_root.join(&key).join(SERVICE);
        if target.exists() {
            let (_, original, _) = recovery_material(paths, &key, &RuntimeContract::pinned())?;
            ensure!(
                read_regular(&target, MAX_SERVICE)? == original,
                "Native browser service has not been restored"
            );
        }
    }

View on GitHub (pinned to b1ed92e5e4)