[DOCS] Mods: document that each event allows only one matcher-less on() registration per plugin
Documentation Type
Missing documentation (feature not documented)
Documentation Location
The plugin-authoring skill (SKILL.md, reference.md) and the On / Register doc comments in the mods type declarations (.claude-plugin/types/claude-code/index.d.ts).
Section/Topic
Registering hooks with on(event, matcher?, hook): how many registrations an event may have
Current Documentation
The docs describe on(event, matcher?, hook) and matchers, but do not say that an event may be registered without a matcher only once per plugin.
What's Wrong or Missing?
claude plugin validate (and the loader) refuses a hooks module that registers the same event twice without a matcher — for any event, not just session.start:
export const register: Register = on => {
on('turn.complete', ($, e, next) => next(e))
on('turn.complete', ($, e, next) => next(e))
}
✘ modules../register.ts: on("turn.complete") is registered twice without a matcher; the first is at ...register.ts:2; ...
Registrations with a matcher may repeat, even with an identical matcher:
on('turn.complete', { reason: 'answer' }, ($, e, next) => next(e))
on('turn.complete', { reason: 'answer' }, ($, e, next) => next(e)) // accepted
Because hooks.json takes a single modules path, a plugin made of several features wires them from one hooks module, and several features naturally observe the same lifecycle events (session.start, turn.complete, prompt.submit). Discovering this rule late forces a redesign: an event-ownership table and artificial matchers such as { isInteractive: true }, { reason: 'answer' }, { origin: { kind: 'composer' } }. Events whose input has no literal discriminant (e.g. session.measure) cannot be shared at all.
Suggested Improvement
- State the rule in
reference.md/ the skill's "A mod in one paragraph" and in theOndoc comment, with the matcher workaround. - Consider allowing repeated matcher-less registrations (chained in registration order, as matcher registrations already are), or provide a way to share an event that has no discriminant.
Impact
Medium - Makes feature difficult to understand
Additional Context
- Claude Code 2.1.296 (type declarations written by 2.1.295), Windows 11.
- Related: #100984 (another rule
claude plugin validateenforces or misses without documentation).