BigPizzaV3/CodexPlusPlus · error · Error

throw new Error({});

Error message

throw new Error({});

What it means

This is not a Rust error but JavaScript source text that build_enabled_bundle() embeds into the generated userscript bundle when fs::read_to_string() fails for an enabled script file (crates/codex-plus-core/src/user_scripts.rs:211). The Rust side deliberately succeeds (fault isolation): one unreadable script does not break bundle generation; instead the wrapped script throws at injection time in the page with the original io::Error message interpolated via json!(). The developer sees it in the browser/page console, not in the manager logs.

Source

Thrown at crates/codex-plus-core/src/user_scripts.rs:211

            "enabled": config.enabled,
            "builtin_dir": self.builtin_dir.to_string_lossy(),
            "user_dir": self.user_dir.to_string_lossy(),
            "scripts": scripts
        }))
    }

    pub fn build_enabled_bundle(&self) -> anyhow::Result<String> {
        let config = self.load_config();
        if !config.enabled {
            return Ok(String::new());
        }
        let mut blocks = Vec::new();
        for script in self.scan_script_files(&config)? {
            if !script.enabled {
                continue;
            }
            let source = fs::read_to_string(&script.path)
                .unwrap_or_else(|error| format!("throw new Error({});", json!(error.to_string())));
            blocks.push(wrap_script(&script, &source));
        }
        Ok(blocks.join("\n"))
    }

    fn scan_scripts(
        &self,
        config: &UserScriptConfig,
        runtime_status: Option<&Value>,
    ) -> anyhow::Result<Vec<Value>> {
        let runtime_scripts = runtime_status
            .and_then(|value| value.get("scripts").or(Some(value)))
            .and_then(Value::as_object);
        Ok(self
            .scan_script_files(config)?
            .into_iter()
            .map(|script| {
                let market = config.market.get(&script.key);

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. Open the browser page console (or the CDP console) — the interpolated message inside throw new Error(...) names the exact io::Error and file, e.g. 'os error 13' (permission) or 'stream did not contain valid UTF-8'
  2. Re-save the script file as UTF-8 (without BOM issues) and rebuild the bundle
  3. Verify the file still exists at the path shown in the scan and is readable by the manager process
  4. If the script is intentionally gone, disable it in the user-script config (enabled=false) or remove its entry so it is skipped instead of throwing

Example fix

# before: script saved as GBK, read_to_string fails, page throws
file: my-theme.user.js  (encoding: GBK)

# after: convert to UTF-8 and rebuild the bundle
iconv -f GBK -t UTF-8 my-theme.user.js > my-theme.user.js.utf8 && mv my-theme.user.js.utf8 my-theme.user.js
Defensive patterns

Strategy: validation

Validate before calling

// Rust, before calling build_enabled_bundle():
for script in scripts.scan_script_files(&config)? {
    if !script.enabled { continue; }
    let bytes = std::fs::read(&script.path)
        .with_context(|| format!("script unreadable: {}", script.path.display()))?;
    std::str::from_utf8(&bytes)
        .with_context(|| format!("script not UTF-8: {}", script.path.display()))?;
}

Type guard

fn script_is_loadable(path: &std::path::Path) -> bool {
    std::fs::read(path)
        .ok()
        .and_then(|b| std::str::from_utf8(&b).ok().map(|_| true))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: Calling UserScripts::build_enabled_bundle() while an enabled script file (1) was deleted/renamed after scan_script_files() enumerated it, (2) is not readable due to OS permissions or an exclusive lock, or (3) contains non-UTF-8 bytes — read_to_string() fails on invalid UTF-8, and the error string is embedded into the JS throw.

Common situations: Script edited and saved in a non-UTF-8 encoding (e.g. GBK on Windows) by an external editor; file held with an exclusive lock by another process (editor/antivirus) on Windows; user manually removed a script directory while the manager was running; script synced by a cloud tool that replaced the file with a placeholder.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/d990726001621a2d. Report an issue: GitHub.