Upgrade to a major version that reworks its state store and the migration looks clean. Everything is there. Then you fix a thread in the old app, switch back to the new one, and the fix is missing. Both copies are intact and they no longer agree. T3 Code v0.1.0 ships this in its upgrade notes, tracked in issue #14871.
Why it happens
The first run of the new version copies the existing database and imports from it. The previous version keeps its own copy and keeps writing to it. Nothing syncs the two afterwards, so any change made on the old side after the import exists only there. There is no error and no warning, which is what makes it expensive to discover late.
The same release flags the same trap one layer down. OpenCode 2 is a separate package that converts the shared database the first time it runs, so 1.x and 2.x cannot be installed side by side on one machine at all.
There is a wire-format half too. A server on the new major and a client on the old one refuse to talk to each other, and whichever side is older is the one that says so. A single stale desktop app or background service is enough to make a whole upgrade look broken.
What to do
Treat the migration as one way. Do the remaining work in the version you are keeping before you switch, and do not plan on bouncing between the two.
Update every installation that talks to the server at the same time - desktop apps, mobile apps, background services and remote machines. The side that refuses the connection will name the machine that is behind, which is the fastest way to find the one you missed.
Where two majors of a tool share one on-disk database and the newer one migrates it in place, install one or the other. Running both is not a fallback. It is how the store gets converted underneath the older binary.