Summary
On every gateway start, a warn log fires for duplicate plugin IDs — most visibly for the msteams plugin. This is a false positive: the same physical plugin is being discovered via multiple paths or origins (e.g. bundled entry shadowed by a config-level entry), and the existing deduplication logic treats any same-ID encounter as a genuine conflict.
Root cause
In src/plugins/manifest-registry.ts, the seenIds map tracks plugin IDs globally. When the same physical plugin is discovered through different origins (e.g. bundled and config), the second candidate triggers the duplicate warning even though both candidates resolve to the same filesystem root.
The existing safeRealpathSync same-path check only suppressed the warning when both candidates had the same origin — cross-origin shadowing (which is by design — config overrides bundled) was still logged as a warning.
Fix
Refactored deduplication to track roots per-origin using two nested maps:
seenRootsById: Map<pluginId, Map<rootKey, SeenIdEntry>>
seenOriginsById: Map<pluginId, Map<PluginOrigin, Set<rootKey>>>
The warn diagnostic now only fires when multiple distinct roots compete within the same precedence bucket. Cross-origin shadowing (config > workspace > global > bundled) is handled silently as intended.
Tests updated to cover the new deduplication behaviour.
Impact
- Eliminates noisy startup warnings for any bundled plugin that is also present in a config-scoped location
- No behaviour change for genuine duplicate ID conflicts (still warned)
- No breaking changes to the registry API or plugin manifest format
Reproduction
Configure a plugin with the same ID as a bundled plugin (e.g. msteams) in your config. Observe warn log on every gateway start even though only one plugin is active.
Additional notes
Happy to contribute a PR if helpful.
Summary
On every gateway start, a
warnlog fires for duplicate plugin IDs — most visibly for themsteamsplugin. This is a false positive: the same physical plugin is being discovered via multiple paths or origins (e.g. bundled entry shadowed by a config-level entry), and the existing deduplication logic treats any same-ID encounter as a genuine conflict.Root cause
In
src/plugins/manifest-registry.ts, theseenIdsmap tracks plugin IDs globally. When the same physical plugin is discovered through different origins (e.g.bundledandconfig), the second candidate triggers the duplicate warning even though both candidates resolve to the same filesystem root.The existing
safeRealpathSyncsame-path check only suppressed the warning when both candidates had the same origin — cross-origin shadowing (which is by design — config overrides bundled) was still logged as a warning.Fix
Refactored deduplication to track roots per-origin using two nested maps:
seenRootsById:Map<pluginId, Map<rootKey, SeenIdEntry>>seenOriginsById:Map<pluginId, Map<PluginOrigin, Set<rootKey>>>The
warndiagnostic now only fires when multiple distinct roots compete within the same precedence bucket. Cross-origin shadowing (config > workspace > global > bundled) is handled silently as intended.Tests updated to cover the new deduplication behaviour.
Impact
Reproduction
Configure a plugin with the same ID as a bundled plugin (e.g. msteams) in your config. Observe warn log on every gateway start even though only one plugin is active.
Additional notes
Happy to contribute a PR if helpful.