scrml.dev v0.7.1
Reference › Errors

E-IDLE-INVALID-VARIANT

<onIdle to=.X/> references a variant X not in the engine's for= enum, OR to= is missing/malformed.

Error Compile-time Added S77 (A5-6) SPEC §51.0.R (normative)

What it means

<onIdle>'s to= target MUST be a variant of the engine's for= enum. The compiler validates this at compile time against the statically-known enum definition. Three failure cases all fire E-IDLE-INVALID-VARIANT:

  • Unknown variant: to=.TypoVariant where TypoVariant is not declared in the engine's for= enum.
  • Missing to=: <onIdle after=5m/> without a target.
  • Malformed to=: non-variant expression in the target slot (e.g., to="Idle" as a string, or to=${@target} as a dynamic expression).

Minimal reproducer

type Phase:enum = { Active, Idle }

<engine for=Phase initial=.Active>
  <Active rule=.Idle/>
  <Idle/>
  <onIdle after=5m to=.Asleep/>
  //               ^^^^^^^^^^^
  //               E-IDLE-INVALID-VARIANT: .Asleep is not a variant of Phase.
</>

How to fix

  1. Use a declared variant. The fix is usually a typo correction: .Asleep.Idle. Or extend the enum if the missing variant SHOULD exist (and remember the additional state-children + rule= contracts).
  2. Add the missing to=. Unlike <onTransition>'s from / to filter pair (where either may be omitted), <onIdle> is a transition-fire (not a handler), so to= is mandatory.
  3. Express dynamic target via derived cell. If you need different idle-targets per app state, model the choice as a derived cell: const <idleTarget> = condition ? .A : .B, then... wait, this isn't actually supported. The to= attribute requires a literal variant per §51.0.R. For dynamic dispatch use a per-state <onTimeout> with rule=-constrained target options.

What this error does NOT check

The compile-time check verifies the variant exists in the engine's enum, but does NOT check whether the current state's rule= permits the target (which is dynamic — the current state at watchdog fire time depends on runtime). That check is deferred to runtime: E-ENGINE-INVALID-TRANSITION fires at runtime if the current state forbids the target.

Related

Specification

Normative text: SPEC §51.0.R (to= must be a variant of the engine's for= enum, required attribute), §34 catalog row. Spec lives at compiler/SPEC.md .