BigPizzaV3/CodexPlusPlus · error
Invalid runtime key
Error message
Invalid runtime key
What it means
prepare() validates the runtime key string before joining it into paths (runtime_root/<key>/...). The key must pass key_valid() (a restricted identifier format); an invalid key could otherwise be used for path traversal or point at a non-existent runtime directory, so preparation fails fast.
Solutions
- Use only runtime keys produced by discover()/the plugin itself (version-identifier style, no slashes or '..')
- Fix or delete the descriptor whose command path yields the invalid key
- Clear the corrupted state and reinstall the plugin so a valid key is generated
Example fix
// before prepare(&paths, "../../etc", &contract)?; // after prepare(&paths, "2026-09-01-abc123", &contract)?;
Defensive patterns
Strategy: validation
Validate before calling
fn key_valid(key: &str) -> bool { !key.is_empty() && key.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') }
if !key_valid(key) { eprintln!("{key:?} is not a valid runtime key"); } Type guard
fn is_valid_runtime_key(key: &str) -> bool {
!key.is_empty() && key != "." && key != ".." && !key.contains(['/', '\\']) && key.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.'))
} Prevention
- Only pass keys obtained from discover()/selected_key into prepare
- Never construct runtime keys from user or file-system input without validation
- Reject keys containing path separators before joining paths
When it happens
Trigger: prepare() is invoked by reconcile_locked with a key that fails key_valid() — e.g. a key containing path separators, '..', empty string, or characters outside the allowed identifier set, typically originating from a malformed descriptor or corrupted state.
Common situations: Hand-edited .mcp.json command paths yielding odd keys; corrupted state files carrying a bad key; keys copied from another platform with different naming rules.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Backup source database is not an allowed local storage path
- 无效的市场主题下载文件名
- 主题市场包含无效 ID:
- invalid Dream Skin destination name
- 主题包必须是 32 MiB 以内的普通 ZIP 文件
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/a784851b8981dd5a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/native_browser.rs:368
}
count += 1;
ensure!(count <= 64, "Too many plugin descriptors");
let descriptor = entry.path().join(".mcp.json");
if !descriptor.exists() {
continue;
}
let data: Value = serde_json::from_slice(&read_regular(&descriptor, 1024 * 1024)?)?;
keys.insert(selected_key(&data, &paths.runtime_root)?);
}
ensure!(
keys.len() <= 1,
"Ambiguous runtime selection; no cache was modified"
);
Ok(keys.into_iter().next())
}
fn prepare(paths: &BrowserPaths, key: &str, contract: &RuntimeContract) -> Result<()> {
ensure!(key_valid(key), "Invalid runtime key");
let runtime = paths.runtime_root.join(key);
let target = runtime.join(SERVICE);
let _runtime_guards = pin_parents(&target)?;
for (file, expected) in &contract.files {
ensure!(
sha(&read_regular(&runtime.join(file), 128 * 1024 * 1024)?) == *expected,
"Unsupported native runtime component: {file}"
);
}
let mut current = read_regular(&target, MAX_SERVICE)?;
let backup_dir = paths.state_root.join(key);
plain_path(&backup_dir)?;
fs::create_dir_all(&backup_dir)?;
let _backup_guards = pin_parents(&backup_dir.join("journal.json"))?;
let backup = backup_dir.join("original.mjs");
let journal_path = backup_dir.join("journal.json");
let control = paths.state_root.join("control.json");
if journal_path.exists() {View on GitHub (pinned to b1ed92e5e4)