scrml.dev v0.7.1
Reference › Errors

E-IDLE-DUPLICATE

An <engine> declares more than one <onIdle> element. One per engine maximum.

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

What it means

<onIdle> is the engine-wide event-timeout watchdog. Per §51.0.R, every engine has AT MOST ONE watchdog — multiple onIdle declarations would race for the same runtime timer slot (composite key <varName>::__idle in _scrml_machine_timers). The compiler rejects multiple at compile time.

Minimal reproducer

type Phase:enum = { Active, Idle, Away }

<engine for=Phase initial=.Active>
  <Active rule=(.Idle | .Away) />
  <Idle rule=.Active />
  <Away rule=.Active />

  <onIdle after=5m  to=.Idle/>
  <onIdle after=30m to=.Away/>
  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  // E-IDLE-DUPLICATE: second <onIdle> in the same engine.
  // One per engine maximum.
</>

How to fix

  1. Pick the right single watchdog. If the intent is "idle for 5 minutes → .Idle; further idle for 30 minutes total → .Away," model the cascade as an <onIdle> that transitions to .Idle, plus an <onTimeout> on the .Idle state-child that transitions to .Away after another 25 minutes.
  2. Use per-state <onTimeout> for state-scoped timing. If two timers reflect different states' timing needs rather than engine-wide silence, they belong on each state-child as <onTimeout> instances, NOT as multiple <onIdle>.

Cascade pattern (recommended)

<engine for=Phase initial=.Active>
  <Active rule=(.Idle | .Away) />
  <Idle rule=(.Active | .Away)>
    <onTimeout after=25m to=.Away/>
  </>
  <Away rule=.Active />

  <onIdle after=5m to=.Idle/>
</>

Composes cleanly: the engine-wide <onIdle> fires after 5m silence → moves to .Idle; entering .Idle arms the per-state <onTimeout> for another 25m → moves to .Away at the 30m total mark.

Related

  • <onIdle> — element reference. Engine-wide watchdog.
  • <onTimeout> — per-state timer; the composition partner for cascade patterns.
  • E-IDLE-MISPLACED — sibling error when <onIdle> sits inside a state-child body.
  • E-IDLE-INVALID-VARIANT — sibling error when to= references a non-enum variant.

Specification

Normative text: SPEC §51.0.R (one-per-engine rule + runtime composite-key encoding), §34 catalog row. Spec lives at compiler/SPEC.md .