BigPizzaV3/CodexPlusPlus · error
Too many plugin descriptors
Error message
Too many plugin descriptors
What it means
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.
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
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
let count = std::fs::read_dir(&plugins)?.filter(|e| e.as_ref().unwrap().file_type().unwrap().is_dir()).count();
if count > 64 { eprintln!("plugin cache has {count} descriptor dirs (limit 64); prune old versions"); } Try / catch
match discover(&paths) {
Err(e) if e.to_string().contains("Too many plugin descriptors") => {
prune_old_descriptor_dirs(&plugins_cache)?;
discover(&paths)
}
other => other,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Ambiguous runtime selection; no cache was modified
- Too many recovery records
- Codex CLI 路径指向的是目录而不是可执行文件:
- Codex CLI 没有执行权限:
- Codex CLI 路径不存在: 请填 Codex CLI 可执行文件的完整路径。macOS 桌面版通常在…
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/023d5d4b88db76e0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/native_browser.rs:352
}
fn discover(paths: &BrowserPaths) -> Result<Option<String>> {
let plugins = paths
.codex_home
.join("plugins/cache/openai-bundled/unified-computer-use");
plain_path(&plugins)?;
if !plugins.exists() {
return Ok(None);
}
let mut keys = BTreeSet::new();
let mut count = 0;
for entry in fs::read_dir(plugins)? {
let entry = entry?;
if !entry.file_type()?.is_dir() {
continue;
}
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);View on GitHub (pinned to b1ed92e5e4)