Day 128: The Model Got Retired Out From Under Me
The chat on pinchy.heypinchy.com said a PDF read failed, and for once the error was honest about why. The audit log had the whole sentence:
tool.pdf failure PDF model failed (ollama-cloud/qwen3-vl:235b-instruct):
410 "qwen3-vl:235b-instruct was retired at 2026-06-16"
Ollama Cloud had retired the vision model out from under a running production instance. Pinchy had pinned it in openclaw.json from a static curated list, so from the moment it was retired, every PDF and every image read on that stack returned a 410. It kept failing until the next upgrade and restart, which is a long time to be blind to attachments.
The third time is a pattern
This is not a one-off. It is the third time a cloud model has disappeared under us: devstral-small-2 started returning 400, gemini-2-preview became “Unknown model,” and now qwen3-vl is retired. Ollama publishes a deprecation table, but there is no advance-notice window and nothing to subscribe to, no feed and no webhook. And /v1/models tells you which models exist, not which ones can do tools or vision, so the capability list you resolved against yesterday can be wrong today. A static curated list baked into a config file is a snapshot of a world that keeps moving.
Self-heal instead of wait
PR #588 stops trusting the snapshot. Model resolution now checks live availability and, when the pinned model is gone, resolves a working replacement at runtime rather than waiting for a human to ship a new config. A retired model becomes a momentary reroute instead of an outage that lasts until the next deploy. This is the same lesson as Day 115: when you build on a runtime and a model catalog you do not own, the correct posture is not to pin harder, it is to expect the ground to move and fail soft when it does. Running Pinchy against your own Ollama or fully self-hosted models is the version of this where the catalog stops moving without your say-so.
A draft is data too
The smaller fix the same day is one I’d wanted for a while. Composer drafts used to live only in memory (PR #589), so a full page reload, or a mobile tab getting evicted after you’d typed but not sent, took your text with it. That is the “switched apps, my prompt is gone” feeling, and it is not acceptable for a tool people work through all day. PR #593 mirrors the draft text to localStorage per conversation as a fallback, so a reload restores what you were writing. File attachments stay in memory on purpose, because File objects don’t serialize cleanly and a half-restored attachment is worse than an honest empty one.
Day 128
The retirement and the lost draft look unrelated, but they are the same admission: state you did not choose to change can still change on you. A cloud provider retires a model; a mobile browser evicts a tab. In both cases the wrong move is to pretend it won’t happen and the right move is to notice quickly and recover without drama. Most of building on other people’s runtimes is exactly this, learning to lose gracefully what was never fully yours to keep.