Skip to content

add_extension silently drops config updates when extension name already loaded #7647

@wpfleger96

Description

@wpfleger96

ExtensionManager::add_extension has a name-only dedup guard at extension_manager.rs:540-542:

if self.extensions.lock().await.contains_key(&sanitized_name) {
    return Ok(());
}

If an extension with the same name is already loaded, the call silently returns Ok(()) regardless of whether the config differs. This means callers cannot update an extension's envs, args, or other config without first calling remove_extension — which kills the subprocess and adds latency.

Impact: In goosed-slackbot, we inject a per-session env var (SLACK_ORIGIN_CHANNEL) into the slack MCP extension config via add_extension. But goosed's background load_extensions_from_session typically wins the race and loads the extension from stored session config (without the env var) before our call arrives. Our add_extension with the updated envs is silently dropped, and the MCP subprocess never sees the env var.

The workaround is calling remove_extension before add_extension, but this restarts the subprocess on every session setup — adding latency and unnecessary churn under heavy load.

Proposed fix: When add_extension is called with a name that's already loaded, compare the incoming config against the loaded config. If they differ (different envs, args, cmd, etc.), remove the old extension and re-add with the new config. If identical, keep the current no-op behavior.

let mut extensions = self.extensions.lock().await;
if let Some(existing) = extensions.get(&sanitized_name) {
    if existing.config_matches(&config) {
        return Ok(());  // truly identical — safe to skip
    }
    // Config changed — need to restart with new config
    extensions.remove(&sanitized_name);
    self.invalidate_tools_cache_and_bump_version().await;
}
drop(extensions);
// ... proceed to spawn new subprocess with updated config

This preserves the optimization (no restart when nothing changed) while allowing legitimate config updates to take effect.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions