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
- 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'
- Re-save the script file as UTF-8 (without BOM issues) and rebuild the bundle
- Verify the file still exists at the path shown in the scan and is readable by the manager process
- 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
- Keep user scripts UTF-8 encoded; configure editors to enforce UTF-8
- Validate readability + UTF-8 of every enabled script before rebuilding the bundle
- Surface per-script read errors in the manager UI instead of shipping a throwing stub into the page
- Disable scripts in config before deleting their files
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.