{"record":{"id":"023d5d4b88db76e0","repo":"BigPizzaV3/CodexPlusPlus","slug":"too-many-plugin-descriptors","errorCode":null,"errorMessage":"Too many plugin descriptors","messagePattern":"Too many plugin descriptors","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/native_browser.rs","lineNumber":352,"sourceCode":"}\n\nfn discover(paths: &BrowserPaths) -> Result<Option<String>> {\n    let plugins = paths\n        .codex_home\n        .join(\"plugins/cache/openai-bundled/unified-computer-use\");\n    plain_path(&plugins)?;\n    if !plugins.exists() {\n        return Ok(None);\n    }\n    let mut keys = BTreeSet::new();\n    let mut count = 0;\n    for entry in fs::read_dir(plugins)? {\n        let entry = entry?;\n        if !entry.file_type()?.is_dir() {\n            continue;\n        }\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);","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/native_browser.rs#L334-L370","documentation":"discover() scans plugin descriptor directories under plugins/cache/openai-bundled/unified-computer-use and caps them at 64 to bound work and avoid pathological states. When more than 64 subdirectories (each potentially holding a .mcp.json) exist, the cache is considered corrupted or manipulated, and discovery aborts instead of guessing which descriptor to use.","triggerScenarios":"discover() (called by reconcile_locked/observation) iterates fs::read_dir on the unified-computer-use cache and the 65th directory entry is reached — e.g. an updater bug duplicated version directories, or backup/restore tooling copied many snapshot dirs into the cache.","commonSituations":"Runaway plugin cache growth after repeated upgrades; backup tools restoring dozens of versioned folders into the cache; sync software (Dropbox etc.) creating conflict copies of descriptor directories.","solutions":["Clean the plugin cache: remove old/duplicate version directories under plugins/cache/openai-bundled/unified-computer-use so ≤64 remain (keep the current one)","Reinstall the plugin to rebuild a minimal cache","Exclude the codex plugin cache from backup/sync tools that duplicate directories"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"let count = std::fs::read_dir(&plugins)?.filter(|e| e.as_ref().unwrap().file_type().unwrap().is_dir()).count();\nif count > 64 { eprintln!(\"plugin cache has {count} descriptor dirs (limit 64); prune old versions\"); }","typeGuard":null,"tryCatchPattern":"match discover(&paths) {\n    Err(e) if e.to_string().contains(\"Too many plugin descriptors\") => {\n        prune_old_descriptor_dirs(&plugins_cache)?;\n        discover(&paths)\n    }\n    other => other,\n}","preventionTips":["Prune old version directories after each plugin upgrade","Exclude the plugin cache from backup/sync tools that duplicate folders","Periodically audit plugins/cache/openai-bundled/unified-computer-use for stray directories"],"tags":["filesystem","plugin-cache","limit-exceeded","native-browser"],"backgroundTag":"value-out-of-range","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"}