E-MATCH-ONTRANSITION-FORBIDDEN
<onTransition>
element used inside a
<match>
block. Transition handlers are engine-only.
What it means
Block-form
<match>
is rules-inert — case analysis on a value, NOT a state
machine. Transitions don't occur in match (the matched-on
value either is or isn't a given variant; nothing
transitions). So
<onTransition>
handlers are structurally meaningless here. The compiler
forbids them — not as a lint, but as an error —
because their presence indicates the wrong primitive.
Minimal reproducer
type Phase:enum = { Idle, Loading, Done }
<match for=Phase>
<Idle></>
<Loading></>
<Done></>
<onTransition to=.Done>
// ^^^^^^^^^^^^^^^^^^^^^^
// E-MATCH-ONTRANSITION-FORBIDDEN: transition handlers are engine-only.
${ analytics.track("done") }
</onTransition>
</match>
How to fix
Promote the
<match>
to
<engine>.
Same exhaustive case-analysis shape; adds active rules + the
ability to declare transition handlers. State-children carry
forward verbatim — the wrapper swap is the commitment
moment. The compiler emits
I-MATCH-PROMOTABLE
on the original site when transition-shape intent is detected.
<engine for=Phase initial=.Idle>
<Idle rule=.Loading />
<Loading rule=.Done />
<Done rule=.Idle />
<onTransition to=.Done>
${ analytics.track("done") }
</onTransition>
</engine>
Why match is rules-inert
Match is one of two Tier-1 shapes (the other being JS-style
match expr { }
value-return form). Both are case analysis on a discriminating
type with compile-time exhaustiveness. NEITHER models
transitions — match looks at WHAT a value IS, not how it
moves between states. The engine wrapper adds:
-
Active
rule=contract per state-child (single-target, multi-target, or wildcard). -
<onTransition>handlers filterable by from / to / once / if. -
effect=attribute for per-rule inline effects. -
<onTimeout>per-state timers and<onIdle>engine-wide watchdog.
Related
- <match> — rules-inert Tier 1; the locus where this error fires.
- <engine> — Tier 2 promotion target; full transition surface.
- <onTransition> — element reference. Legal only inside <engine>.
- E-MATCH-EFFECT-FORBIDDEN — companion error for effect= attribute (also engine-only).
- W-MATCH-RULE-INERT — rule= warning (legal but inert; promote to engine to activate).
Specification
Normative text: SPEC §18.0.2 (match attribute legality: rule= inert / effect= forbidden / onTransition forbidden), §51.0.H (<onTransition> in engine context), §34 catalog row. Spec lives at compiler/SPEC.md .