E0098: duplicate_edge
E0098 duplicate_edge — the same transition declared twice.
A compile-time error of soma check, the checker of the Soma programming language (soma explain E0098).
The rule
soma check reports E0098 when two edges of a state machine cover the same move from the same state with different guards, here the wildcard * -> cancelled and paid -> cancelled { guard { refunded } }. A transition() takes the first edge that matches, so the later edge's guard is never evaluated (or, in the other order, the first edge's guard refuses a move the second allows). Declare each move once: keep the guarded state out of the wildcard with except [...], adding it to the states already listed there.
A program that triggers it
wrong.cell
cell Orders {
face {
signal cancel(id: String, refunded: Bool) -> String
}
state order {
initial: placed
placed -> paid
paid -> shipped
* -> cancelled except [shipped]
paid -> cancelled { guard { refunded } }
}
on cancel(id: String, refunded: Bool) {
transition(id, "cancelled")
return get_status(id)
}
}What soma check prints:
$ soma check wrong.cell
error: `paid -> cancelled { guard … }` repeats the move paid -> cancelled that `* -> cancelled` already declares with no guard — a transition takes the first edge that matches, so this guard is never evaluated there. Declare each move once, or keep the state out of the wildcard: `* -> cancelled except [paid]`
--> wrong.cell:10:9
|
10 | paid -> cancelled { guard { refunded } }
| ^
= code: E0098
✗ 1 error(s), 0 warning(s).The fix field of soma check --json: a transition takes the first edge that matches, so this guard is never evaluated there. Declare each move once, or keep the state out of the wildcard: `* -> cancelled except [paid]`
The fix
On line 9, * -> cancelled except [shipped] becomes * -> cancelled except [shipped, paid].
wrong.cell → right.cell
--- wrong.cell
+++ right.cell
@@ -7,5 +7,5 @@
placed -> paid
paid -> shipped
- * -> cancelled except [shipped]
+ * -> cancelled except [shipped, paid]
paid -> cancelled { guard { refunded } }
}With the fix, soma check accepts the program:
$ soma check right.cell
✓ All checks passed.