This week we didn't ship a headline feature. We spent it on a production evidence sweep instead: reading real error traces from Vercel and Supabase, and fixing the exact failures they pointed to. That included a login bug that could quietly lock people out of their account, a billing error on trial upgrades, a chat crash triggered by one malformed file reference, and three smaller reliability cleanups. None of these are flashy. All of them were affecting real sessions.
If last week was about MCP logins and a rebuilt developer page, this week is the unglamorous half of shipping software: finding the edge case that only shows up under real traffic, and closing it before it happens to more people.
What shipped this week
| Fix | Category | Who it's for |
|---|---|---|
| Malformed auth cookie recovery | Fixed | Anyone who got logged out unexpectedly |
| No-op trial upgrade guard | Fixed | Users upgrading or adjusting a trial plan |
| Invalid search file ID guard | Fixed | Anyone chatting with attached documents |
| Tool-loop final answer fix | Fixed | Anyone using AI agents that call tools |
| Image edit response classification | Fixed | Users editing AI-generated images |
| Transcription cleanup hardening | Fixed | Voice dictation and transcription users |
| Retired page redirects | Improved | Anyone following an old bookmark or link |
Login shouldn't lock you out
The first bug we found this week was ugly in a specific way: it failed silently on the client, so most people who hit it just saw a login screen refresh and figured it was a fluke. Under the hood, a malformed Supabase session cookie was causing our auth client to throw a TypeError while trying to recover and refresh the session — Cannot create property 'user' on string. When that happened, the request that depended on the session, like /api/stats, would fail closed with a 401 instead of recovering.
We traced this back to a one-hour production window where it happened at least once, then added a guard around cookie recovery so a malformed cookie gets discarded and a fresh session gets requested instead of crashing the whole auth flow. If you've ever been mysteriously logged out and had to sign in again for no clear reason, this is very likely why, and it should not happen anymore.
There's no setting to change here — this runs automatically every time you load Writingmate at writingmate.ai/chat.
Billing and chat get sturdier under real traffic
Two more fixes came out of the same kind of production forensics. First, a billing one: if you upgraded a trial subscription in a way that didn't actually change your price or quantity, Stripe would reject the update with a 400 and our route would surface that as a raw 500 error. We now check for a no-op change before calling Stripe, so switching between equivalent trial states doesn't throw an error page at you anymore.
Second, a chat one. If a message referenced a file search ID that wasn't a valid UUID, the request would still make it to Supabase, which would reject it with a Postgres invalid UUID syntax error deep in the stack. That's not a helpful place for a validation error to live. We now reject invalid search file IDs before they ever reach the database, so a bad reference fails fast with a clear error instead of a confusing one.
The third fix in this group is about agents specifically. When an AI agent in Writingmate calls tools repeatedly, like searching, then reading a file, then searching again, there was a path where the model's final answer after that loop could get dropped instead of returned to you. You'd see the agent "finish" with nothing to show for it. We fixed the response handling so the final answer always comes back, even after several rounds of tool calls. This matters most for the agents and MCP tooling covered on writingmate.ai/developers, where multi-step tool use is the whole point.
Image editing and transcription cleanups
Image editing had its own edge case. Occasionally the upstream image provider would return an HTTP 200 with no actual image in the response body, our documented image_url field just wasn't there. The route would log "No image generated in response" and then fail in a way that looked like a server crash rather than a provider problem. We now classify that specific case as a proper 502 from the provider, so the error you see actually matches what happened. This applies wherever you edit an AI-generated image, including the mask-based region editor.
On the transcription side, we hardened the cleanup prompt that runs after Groq/Whisper transcribes your audio. The previous version could occasionally invent an extra trailing sentence or repeat a phrase in a loop at the end of a transcript, especially on shorter clips. We isolated the transcript, formatting instructions, and language context into explicit boundaries in the prompt and added an instruction to preserve every clause without inventing suffixes. This runs automatically on every transcription, there's nothing to turn on.
Fixed this week
- Malformed Supabase auth cookies no longer cause a 401 that logs you out unexpectedly
- No-op Stripe trial upgrades no longer throw a billing error
- Invalid file search IDs are now rejected before they reach the database, instead of surfacing a raw Postgres error
- AI agents using tools in a loop no longer drop their final answer
- Image edit requests with an incomplete provider response now return a clear 502 instead of a silent failure
- Transcription cleanup no longer invents trailing sentences or repeats phrases
- Retired public pages now redirect to their current index instead of showing a 404
Thanks for putting up with these rough edges while we tracked them down, they're the kind of bug that's hard to see until someone hits it in production. You can browse every past update, including last week's MCP login launch, on writingmate.ai/changelog.
— Artem
Questions about this week's fixes
Sources
Written by
Artem Vysotsky
Ex-Staff Engineer at Meta. Building the technical foundation to make AI accessible to everyone.
Reviewed by
Sergey Vysotsky
Ex-Chief Editor / PM at Mosaic. Passionate about making AI accessible and affordable for everyone.