The canonical codec met a value outside the protocol: an unsafe integer, NaN/±Infinity, a
Map/Set/RegExp/class instance, a function or symbol, an undefined inside an array, or an
invalid Date. The message names the exact path ($.swap.amounts[1]).
The codec is deliberately total rather than lenient: “same operation ⇒ same bytes” is a protocol
guarantee, and a silent coercion (an unsafe integer rounding, an undefined becoming null) would
break it invisibly.
Fix — pass a bigint or a string for large integers, a number for sub-second timestamps, and a
plain object/array for structures. A route-level encode receives the complete CDC row.