Async hooks supported
Why it matters
Most real-world plugins need to do async work — call external APIs, query databases, read files. If the hook invocation loop does not await handler return values, any plugin that returns a Promise appears to work but silently drops its errors. The host continues as though the handler succeeded while the underlying operation failed. This creates data integrity issues in write operations, invisible failures in webhook processors, and phantom results in request pipelines. ISO 25010 reliability.fault-tolerance requires that errors propagate to where they can be handled, not vanish into unhandled rejections.
Severity rationale
High because async handlers whose Promises are not awaited silently swallow errors, making plugin failures invisible and corrupting write pipelines without any logged indication.
Remediation
Audit every hook invocation site and ensure the loop awaits each handler. For sequential semantics, use for...of with await; for parallel semantics, use Promise.all. Unhandled rejections must be caught and attributed to the specific plugin.
async function invokeHook(name: string, context: HookContext): Promise<void> {
const handlers = this.registry.get(name) ?? [];
for (const handler of handlers) {
await handler(context); // awaits each handler in sequence
}
}
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 — async errors from plugin handlers must be caught and not crash the host
- iso-25010:2011 · maintainability.modularity
Taxons
History
- 2026-04-18·v1.0.0·Initial import from plugin-extension-architecture·automated