Conflicting plugins detected
Why it matters
When two plugins register the same route, command ID, or decorator key and the host silently accepts both, behavior depends on which plugin loaded last — an implementation detail that changes across restarts, deploys, and config edits. ISO 25010 maintainability.modularity requires that namespace boundaries be enforced; silent last-wins collision is a namespace boundary failure. Operators cannot predict or debug behavior that changes based on plugin load order with no logged conflict.
Severity rationale
Low because undetected duplicate plugin IDs or namespace collisions produce load-order-dependent behavior that is indistinguishable from intentional configuration until a conflict silently activates the wrong handler.
Remediation
Reject duplicate plugin names at load time with an explicit PluginConflictError. Extend conflict detection to namespace collisions (duplicate routes, commands, or decorator keys) as the plugin ecosystem grows.
function loadPlugin(manifest: PluginManifest) {
if (this.plugins.has(manifest.name)) {
throw new PluginConflictError(
`Plugin "${manifest.name}" is already loaded. Cannot load a second plugin with the same name.`
);
}
for (const conflict of manifest.conflicts ?? []) {
if (this.plugins.has(conflict)) {
throw new PluginConflictError(
`Plugin "${manifest.name}" conflicts with loaded plugin "${conflict}".`
);
}
}
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Plugin / Extension Architecture Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- iso-25010:2011 · maintainability.modularity — Modularity — conflict detection prevents silent last-wins semantics when plugins share namespaces or hooks
Taxons
History
- 2026-04-18·v1.0.0·Initial import from plugin-extension-architecture·automated