{"record":{"id":"a784851b8981dd5a","repo":"BigPizzaV3/CodexPlusPlus","slug":"invalid-runtime-key","errorCode":null,"errorMessage":"Invalid runtime key","messagePattern":"Invalid runtime key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/native_browser.rs","lineNumber":368,"sourceCode":"        }\n        count += 1;\n        ensure!(count <= 64, \"Too many plugin descriptors\");\n        let descriptor = entry.path().join(\".mcp.json\");\n        if !descriptor.exists() {\n            continue;\n        }\n        let data: Value = serde_json::from_slice(&read_regular(&descriptor, 1024 * 1024)?)?;\n        keys.insert(selected_key(&data, &paths.runtime_root)?);\n    }\n    ensure!(\n        keys.len() <= 1,\n        \"Ambiguous runtime selection; no cache was modified\"\n    );\n    Ok(keys.into_iter().next())\n}\n\nfn prepare(paths: &BrowserPaths, key: &str, contract: &RuntimeContract) -> Result<()> {\n    ensure!(key_valid(key), \"Invalid runtime key\");\n    let runtime = paths.runtime_root.join(key);\n    let target = runtime.join(SERVICE);\n    let _runtime_guards = pin_parents(&target)?;\n    for (file, expected) in &contract.files {\n        ensure!(\n            sha(&read_regular(&runtime.join(file), 128 * 1024 * 1024)?) == *expected,\n            \"Unsupported native runtime component: {file}\"\n        );\n    }\n    let mut current = read_regular(&target, MAX_SERVICE)?;\n    let backup_dir = paths.state_root.join(key);\n    plain_path(&backup_dir)?;\n    fs::create_dir_all(&backup_dir)?;\n    let _backup_guards = pin_parents(&backup_dir.join(\"journal.json\"))?;\n    let backup = backup_dir.join(\"original.mjs\");\n    let journal_path = backup_dir.join(\"journal.json\");\n    let control = paths.state_root.join(\"control.json\");\n    if journal_path.exists() {","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/native_browser.rs#L350-L386","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nprepare(&paths, \"../../etc\", &contract)?;\n// after\nprepare(&paths, \"2026-09-01-abc123\", &contract)?;","handlingStrategy":"validation","validationCode":"fn key_valid(key: &str) -> bool { !key.is_empty() && key.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') }\nif !key_valid(key) { eprintln!(\"{key:?} is not a valid runtime key\"); }","typeGuard":"fn is_valid_runtime_key(key: &str) -> bool {\n    !key.is_empty() && key != \".\" && key != \"..\" && !key.contains(['/', '\\\\']) && key.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.'))\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["validation","path-safety","native-browser","identifier"],"backgroundTag":"invalid-identifier-format","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}