Closed bug report

kicad_add_zone returns a revision the async zone fill makes stale a moment later: the next edit gets stale_board

John Lauer · ·closed by John Lauer

Symptom

kicad_add_zone answers refilled: true with a board revision, and kicad_zone_state straight after answers the same revision. A moment later the live board has a different revision, so the next edit that passes that revision is refused with stale_board ("expectedRevision must match the current live board"), and every chained edit after it fails the same way.

Seen on arav-rog (KiCad 10.0.3) in the verb battery, 2026-09-21, bridge 1.0.50: remove_zone, apply_zone_plan and the three silk batch verbs all stale_board. Intermittent: of two reruns of the live-board phase one failed the same way and one passed all 23 verbs. ConfRoomROG (10.0.5) passed. Nothing in this code path changed between 1.0.37 and 1.0.50, and 1.0.37/1.0.38 passed on arav-rog, so this is timing, not a regression.

add_zone    ok  revision 1608735e...  refilled:true
zone_state  ok  revision 1608735e...
remove_zone stale_board  currentRevision dae81f97...

Likely cause

KiCad fills zones asynchronously. The add verb commits, asks for a fill, and reads the revision before the fill has landed; the fill then changes the board.

Fix options

  1. After the commit, poll the revision until it is stable across two reads (bounded, a few seconds) before answering, so the revision in the reply is the board the caller will see.
  2. Or answer refillPending: true and no revision, the same contract kicad_zone_state {refill:true} already has (skills/kicad-copper-pours step 5), and tell the caller to read the revision with kicad_zone_state once the fill settles.

The refusal itself is correct: the bridge must never apply an edit against a board it has not seen. What is wrong is that its own reply handed the caller a revision that was about to be stale.

1 Reply

John Lauer ·

Fixed in 1.0.51 (insiders), option 1.

kicad_add_zone now waits for KiCad's asynchronous fill before answering: after the refill request it polls the board revision until it has moved away from the pre-fill board and read identically three times in a row (300 ms apart, busy reads retried, bounded at 12 s). A fill that changes nothing is accepted after 3 s of quiet. The reply carries revisionSettled; when the fill never settles it says so and points at kicad_zone_state rather than handing out a revision it knows may be stale. Unit tests cover a late fill, a no-op fill, and a board that never stops changing.

Proof on arav-rog (KiCad 10.0.3), where it reproduced:

Build Live-board phase runs Result
1.0.50 3 2 failed with stale_board from remove_zone on
1.0.51 5 5 passed, 23/23 verbs each, revisionSettled: true, refilled: true every time

Closing as fixed. Reopen if a stale_board shows up right after kicad_add_zone again.

John Lauer closed this ·

Log in to reply.