July 29, 2026

The Context-Window Bug Had a Second Door

A refused ping was killing providers the same way a dead host did, and a date divider that couldn't tell what year it was made phone and desktop disagree with each other.

Fixed a context-window bug four days ago. It came back today through a different door.

Same shape every time: something needs to know how much context a model can hold, and if it doesn’t, the whole provider dies — one empty field kills every turn on that host until someone notices. On July 26 the caching half got sorted: one column, self-healing on the next call. Today was the measuring half.

Four of five provider paths could come back with nothing. A newer model slug missing from the local cache. An SDK hiccup. A host that just doesn’t report its context length. A published table that predates the model you’re actually talking to. Only the models with one figure published for everything they serve were safe — everyone else was measuring by hoping. Fixed it by drawing the line at liveness instead of knowledge: if a host answers at all, it gets sized, its own reported figure if it volunteers one, a family-based default if it doesn’t. A host that’s genuinely unreachable still comes back empty, so a server that’s briefly down doesn’t get a made-up number stapled to it forever. For OpenAI-compatible hosts specifically, swapped two endpoint probes that only worked against one runtime for a five-token completion ping — any host that can answer a completion can be sized, full stop.

Except a ping can come back with a refusal instead of an answer, and the code treated those the same as no answer at all — both landed as nothing, both killed the provider. The door that opened: newer reasoning models reject the standard token-limit parameter outright and demand a different one, so any slug newer than what’s hardcoded pings, gets a routine error back, and the provider drops dead exactly like before. Wrong instinct — a refusal is proof the host is up. The code now tells the two apart properly: a refusal sizes like any live host, and the real problem — a bad parameter — surfaces later, at send time, where the error message actually names it instead of masquerading as “can’t determine the context window.” Wrote both rulings down so the next person debugging this doesn’t relitigate them from scratch.

The other bug today was dumber and more embarrassing. The date divider on a chat’s timeline pulled a message’s calendar day straight out of its display timestamp — a string like “29 Jul 10:35” with no year in it. Hand that to a date parser and it invents one, and which year it invents depends on the engine: one picks 2000, another picks 2001. The divider showed the weekday for a date twenty-six years off, the “Today” label never matched because “2000-07-29” isn’t “2026-07-29,” and the same build disagreed with itself between a phone and a desktop. The backend already knows the day, in the user’s actual timezone — it now sends that day straight through and the client stamps it verbatim instead of guessing from a string never meant to carry a year. Added a test pinning a message to 11:40pm UTC, already the next day in Malta, to keep “the user’s calendar, not the server’s” true going forward.

Smaller thing rode along: ported the MCP server and client onto the 2.0 API before 1.x goes stale underneath everything built on it.

Two rulings on record now for provider sizing — the next weird host fits one or teaches a third.

  • Rewrote context-window sizing to draw the line at whether a host answers at all, not whether its answer is complete — a live host always gets sized, an unreachable one stays blank for the next probe

  • Replaced endpoint probing that only worked for one runtime with a universal completion ping for OpenAI-compatible hosts

  • Fixed a second failure mode where a refused ping (bad parameter, unrecognized slug) was treated as no response and killed the provider the same way a dead host would

  • Fixed the chat timeline’s date dividers reading the wrong weekday and never showing “Today” — caused by parsing a yearless display string, which different engines resolved to different invented years

  • Ported the MCP server and client onto the 2.0 API