An automation that throws an error gets fixed the same day. An automation that silently does nothing runs for months.
These six are drawn from real incidents. Every one type-checked, deployed cleanly, and appeared configured in the UI.
1. A setting nobody reads
A field is added to the schema, sent over the wire, and rendered in the UI, and no code anywhere ever reads it. The control is live, the value persists, and it changes nothing.
The check: before shipping any config field, grep for its reader. If there is not one, remove the control or disable it. A disabled control is honest; a live control that does nothing is a bug wearing a costume.
2. A writer without its inverse
Something derived from the canvas gets flattened on save, and the loader cannot rebuild it. The next save writes the flattened version back, and the original structure is gone.
The check: save, reload, save again, and compare. The two saves must be byte-identical. Keep the serializer and its deserializer in one file so they are edited together.
3. A clamp on a signed value
Jump arithmetic gets a defensive Math.max(0, x) or x > 0 ? x : 1. Forward jumps keep working, so tests pass. Backward jumps, which is how every menu loop navigates, silently advance by one instead.
The check: grep new navigation code for clamps. Test a flow whose step 1 is also a jump target.
4. An empty string beating a fallback
A builder persists untouched text fields as "", never null. ?? only falls through on null and undefined, so the empty string wins the chain and starves every fallback behind it.
The check: treat blank as absent wherever a builder-authored optional string feeds a fallback chain.
5. Position used as identity
A change detector keyed on row index. Insert one row near the top of a hundred-row sheet and ninety-eight rows look changed.
The check: key on a stable business value, and detect one automatically when a source is connected, so the protection is on from the first sync.
6. A gate that fails open
A condition evaluates correctly and takes the NO branch, but the NO branch is unwired, so it falls through to the next step, which is exactly what YES would have done. The gate guarded nothing.
The check: an unwired branch ends the run. Always. The cost of a gate wrongly closed is an automation that does not fire; the cost of one wrongly open is an action taken against somebody who never opted in.
The common thread
Types catch shape. None of these are shape problems. Every one is a wiring problem, and the only thing that catches a wiring problem is exercising the path with real data and checking that the value written is the value read.
Every run is logged
Per-step results, the trigger payload and the resolved context, on every execution.



