E-STRUCTURAL-ELEMENT-MISPLACED
A scrml-defined structural element appears outside the locus it belongs to.
What it means
scrml defines a small set of structural elements
that look like HTML tags but are scrml-language constructs:
<engine>,
<match>,
<errors>,
<onTransition>,
<onTimeout>,
<onIdle>,
<page>.
Each has a strict owning locus — the place
it's grammatical to use it. Outside that locus, the compiler
emits E-STRUCTURAL-ELEMENT-MISPLACED.
Owning loci
| Element | Grammatical only as… | SPEC |
|---|---|---|
| <onTransition> | Child of <engine> |
§51.0.H |
| <onTimeout> | Child of an engine state-child | §51.0.M |
| <onIdle> | Child of <engine> (sibling of state-children; one per engine) |
§51.0.R (specific code: E-IDLE-MISPLACED) |
| <errors> | Anywhere with a parent context that supports validity-surface rendering | §55.8 |
| <page> | Child of <program> in MPA mode |
§40.8 |
| <engine> / <match> | File scope or inside an engine's composite state-child (engines may nest per §51.0.K) | §51 / §18.0 |
Minimal reproducer
<onTransition>
at file scope, outside any engine:
<onTransition from=.A to=.B>
${ log("transitioned") }
</onTransition>
E-STRUCTURAL-ELEMENT-MISPLACED fires at the opener —
<onTransition>
outside <engine>.
<onTimeout>
at file scope:
<onTimeout after=5s to=.Done/>
Same error —
<onTimeout>
outside an engine state-child.
How to fix
-
Move the element inside its owning locus.
For
<onTransition>, wrap it in an engine declaration. For<onTimeout>, place it inside a state-child body. - If the element shouldn't exist, delete it. Misplacement sometimes reveals dead code that was moved away from its engine during refactoring.
-
Check the rules-inert siblings.
Inside a
<match>block (§18.0.2),<onTransition>fires the more specific E-MATCH-ONTRANSITION-FORBIDDEN instead. Promote the match to an engine if you need transition effects.
Specific misplacement codes
Some elements have a dedicated misplacement code with sharper messaging:
-
<onIdle>inside a state-child body → E-IDLE-MISPLACED (more specific than E-STRUCTURAL-ELEMENT-MISPLACED; directs to<onTimeout>instead). -
<onTransition>inside a<match>block → E-MATCH-ONTRANSITION-FORBIDDEN. -
effect=attribute on a state-child inside<match>→ E-MATCH-EFFECT-FORBIDDEN.
When a more specific code applies, the compiler fires that one instead of the generic E-STRUCTURAL-ELEMENT-MISPLACED.
Related
- <engine> — the canonical owner of onTransition / onTimeout / onIdle.
- <match> — rules-inert; effect=/onTransition forbidden here. Promote to engine instead.
- <errors> — renders the auto-synthesized validity surface; needs a parent context with validators.
- E-NAME-COLLIDES-RESERVED — companion error when a user component name collides with a reserved structural-element identifier.
Specification
Normative text: SPEC §4.15 (structural-element registry), §24.4 (HTML-aware element classification), per-element owning sections (§51.0.H / §51.0.M / §51.0.R / §55.8 / §40.8), §34 catalog row. Spec lives at compiler/SPEC.md .