All packsOffline Sync EngineSolve
offline queue schema migration versioned messages
An app upgrade can leave the offline queue speaking the old schema
A device with a full offline queue that upgrades to a new app version can push messages shaped for a schema the server no longer accepts.
What goes wrong
A device that's been offline for a while, accumulating queued writes, and then receives an app update before reconnecting now holds an outbox full of messages shaped for the old wire schema -- while the server (and every other already-updated client) expects the new one. Pushing those old-shaped messages either corrupts data under the new schema's assumptions or fails outright, and the failure can strand a real user's legitimately queued offline work.
Why agents get it wrong
Schema migrations are normally reasoned about as a server-and-database concern -- run a migration, update the code, done. A client-side outbox holding messages written under a previous version of the wire format is a consequence specific to offline-first sync that doesn't come up in a typical online CRUD app, where there's no persisted client-side queue spanning an app upgrade to begin with.
What Offline Sync Engine pre-decides
Every outbox entry stores the schemaVersion it was written under, and migrateOutbox() walks each queued message forward through a registry of per-version migration functions before anything gets pushed -- SyncEngine.sync() calls it first, unconditionally, so an app upgrade with a full offline queue migrates the queue before ever touching the network. The server additionally accepts only the current wire version and returns 426 upgrade_required on anything else, so a client that somehow skipped migration fails loudly instead of writing malformed data.
Source: ARCHITECTURE.md 'Schema migration of queued mutations (decided)'