Hmbown/CodeWhale · error · anyhow::Error
active plugin registry is missing its pre-dotenv…
Error message
active plugin registry is missing its pre-dotenv environment snapshot
What it means
When merging plugin-provided MCP servers into the config, the code needs the plugin registry's captured pre-dotenv environment snapshot (the host environment as it was before .env loading). If the active registry has none, merging cannot proceed safely and fails with this error instead of silently using a wrong environment.
Solutions
- Ensure the plugin registry is constructed via the standard path that captures host_environment() before dotenv loading
- Fix initialization order: capture the environment snapshot before any .env file is applied
- If constructing a registry manually, supply the host environment snapshot explicitly
Defensive patterns
Strategy: validation
Validate before calling
// ensure the registry captured its environment snapshot before merging
anyhow::ensure!(
registry.host_environment().is_some(),
"plugin registry built without pre-dotenv env snapshot"
); Try / catch
match merge_plugin_mcp_servers(config) {
Err(e) if e.to_string().contains("pre-dotenv environment snapshot") => rebuild_registry_with_env_snapshot_then_retry(),
other => other,
} Prevention
- Always construct the plugin registry through the standard initialization path
- Capture the host environment before applying any .env files
- Add an invariant test that host_environment() is Some after normal init
When it happens
Trigger: Calling the plugin MCP merge path when registry.host_environment() returns None — i.e. the registry was constructed without capturing the environment snapshot before dotenv was applied.
Common situations: Plugin registry initialized by an alternate entry point that skipped the snapshot; a refactor changed registry construction order so the env capture no longer happens before dotenv loads.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Failed to store MCP connection for
- MCP connection disappeared for
- A managed, project or plugin connector already uses this…
- Absolute path should not warn
- app_denied
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/42611e8450bed454.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp.rs:5437
fn merge_plugin_mcp_servers(
config: McpConfig,
registry: &crate::plugins::PluginRegistry,
) -> Result<McpConfig> {
let Some(state_path) = registry.state_path().map(Path::to_path_buf) else {
return Ok(config);
};
let plugins = registry
.active_plugins()
.into_iter()
.filter_map(|plugin| {
plugin
.authority(state_path.clone(), registry.workspace().to_path_buf())
.map(|authority| (plugin.name().to_string(), plugin.clone(), authority))
})
.collect::<Vec<_>>();
let host_environment = registry.host_environment().ok_or_else(|| {
anyhow::anyhow!("active plugin registry is missing its pre-dotenv environment snapshot")
})?;
merge_plugin_mcp_servers_from_plugins_with_environment(config, plugins, host_environment)
}
fn merge_plugin_mcp_servers_from_plugins_with_environment(
mut config: McpConfig,
plugins: impl IntoIterator<
Item = (
String,
crate::plugins::types::LoadedPlugin,
crate::plugins::types::PluginAuthority,
),
>,
host_environment: Arc<crate::plugins::HostEnvironment>,
) -> Result<McpConfig> {
for (plugin_name, plugin, authority) in plugins {
// Adapter-level denial keeps headless paths fail-closed even if a
// future caller accidentally passes the full inventory instead of theView on GitHub (pinned to 73e0f67d83)