A value we fail to parse comes back as an empty queue. A store we fail to read throws.
Those two failures are not the same, and collapsing them into one is how offline apps quietly lose writes.
In offlinequeue, our open-source offline write queue, decode is the single place where a stored value turns into a queue. It returns an empty operation list in exactly three cases: the raw value is falsy, JSON.parse throws on the string, or the parsed value fails an Array.isArray check. A key collision or a half-written record therefore reads as no pending work, instead of a queue of nonsense that the rest of the system then tries to replay.
What decode does not do is catch anything coming out of the store itself. The key-value adapter awaits getItem with no try around it. The MMKV adapter calls getString the same way. A getItem that rejects or a getString that throws travels out of load to the caller rather than getting flattened into an empty result.
That split is deliberate.
A value you could read but that is not a queue is survivable. An unreadable queue is bad, and an app that will not start is worse.
A store that answered nothing is a different thing entirely. It has not told us the device holds no pending work. It has told us nothing at all. Flatten that into an empty queue and the next save writes over operations we never saw, and that silent loss is the specific problem this library exists to prevent.
Saving is symmetric and swallows nothing: the adapters hand the serialized operations straight to setItem or set, errors included. Both default their key parameter to the same default key. The in-memory adapter returns copies of a held array and neither throws nor decodes, which keeps tests honest about ordering without pretending storage can fail.
The rule we keep arriving at, across payment queues and sync layers alike: only default when absence is something you actually learned. There is nothing stored and we could not find out what is stored deserve different code paths.
That line sits somewhere in your own persistence layer, and it is probably worth knowing where you put it.