Hook unregistration supported
Why it matters
When hook handlers cannot be unregistered, disabling a plugin through the admin UI is cosmetic. The plugin's handlers keep firing on every request, every event, every lifecycle call — consuming CPU, accessing data, and potentially interfering with replacement plugins. CWE-404 (Improper Resource Shutdown) applies directly: the resource — an active event handler — is never released. In long-running hosts with hot-reload or dynamic plugin enable/disable, unregistration is the only mechanism that makes plugin state changes observable without a restart.
Severity rationale
Medium because the inability to unregister hook handlers makes plugin disable purely cosmetic — handlers keep running after removal, making clean hot-reload architecturally impossible.
Remediation
Have every registration call return a disposable. When the plugin manager deactivates a plugin, call dispose() on every disposable that plugin registered. This pattern composes cleanly with VS Code's context.subscriptions model.
on(hook: string, handler: Function): Disposable {
this.handlers.get(hook)?.push(handler);
return {
dispose: () => {
const handlers = this.handlers.get(hook);
if (handlers) {
const idx = handlers.indexOf(handler);
if (idx >= 0) handlers.splice(idx, 1);
}
}
};
}
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 · reliability.fault-tolerance — Fault tolerance — unregistration prevents resource leaks when plugins are disabled or the host shuts down
- cwe · CWE-404 — Improper Resource Shutdown or Release
Taxons
History
- 2026-04-18·v1.0.0·Initial import from plugin-extension-architecture·automated