

When the product has to say no
The most-read sentence in an AI product is the one it shows when it refuses, and it is almost always the only sentence nobody designed. It gets written in the pull request that adds the limit, by someone reasonably focused on not falling over, and then it becomes permanent โ because it isn't a feature, so it never gets a review, and it only fires for people who are already annoyed, which makes it invisible in every demo.
What that costs, when somebody measures it
DeepSeek shipped exactly this in May. From the afternoon of 29 May, repeatedly regenerating or editing a message triggered a usage cap โ BigGo reported roughly three to six regenerations in standard mode, about three in expert mode, around six edits, lifting on its own after fifteen to thirty minutes.
The limits themselves are defensible. Every regeneration is a full inference pass over the whole context, and a service under load has to do something. What followed is the interesting part.
The App Store release notes for that version said, in full: "- Search your chat history - Fixed some known issues." No mention of the caps. MWM, writing on 31 May, recorded what happened to the rating: 3.88 stars for the previous version, 2.66 for this one. A drop of 1.22 points, on a version whose headline feature was chat search.
Reviewers called the restrictions "cruel" and "too restricting." A GitHub issue three weeks later asked for them to be removed outright โ "I can't edit or regenerate after reached those limits" โ and had no maintainer response when I read it.
What BigGo records as the actual grievance is not the cap. It's that people found out through a pop-up.
A rating is a blunt instrument and a star average moves for several reasons at once; the same release also cut file uploads and web search from expert mode, so the 1.22 is not attributable to the message alone. But the direction is not ambiguous, and the sequence is: ship a limit, don't mention it, let the dialog explain it, lose a point of rating.
Four things a refusal owes the user
Every one of these is a sentence, and the absence of each is a support ticket.
| The question | What the message usually does | |
|---|---|---|
| What happened | Is this a limit, a fault, or a judgement about my request? | Says "too frequently", which could be any of the three |
| Whose | Is it me, my plan, or everyone right now? | Silent โ so the user assumes the worst reading |
| When | Does this clear in a minute, an hour, or at a billing date? | "Try again later" |
| What survives | Is my draft still there? | Silent, which is why people stop trusting the thing |
The third is the one that changes behaviour. A person told about twenty minutes goes and does something else. A person told later refreshes โ which is worse for them and worse for the server that refused them, since the rapid retrying that gets flagged as abuse is manufactured by the vagueness. The server knows the number. It is in the code that produced the refusal.
The fourth is the one that costs you the relationship. Poppy is a voice-first assistant for teachers, and its realistic moment of use is ninety seconds between classes with their hands full. A refusal that also loses what they dictated isn't an inconvenience; it is the whole session. Whether a refusal is survivable depends almost entirely on what it preserves, and that is decided long before anyone writes the message.
The limit is a product surface
The fix is not a copywriting pass over the strings. It is deciding, at the moment you add the limit, that the limit is part of the product: it has states, it has a duration the server already knows, and it has a relationship to the work in progress. All three facts exist in the code at the point of refusal. Almost none of them reach the sentence.
Two things follow from treating it that way. The limits get documented somewhere a user can reach โ a page listing the caps by plan and by mode, what the window is, and what happens to a draft โ and the dialog links to it. And the change gets announced before it ships, which is the cheap half: the grievance in the DeepSeek case was the surprise, not the cap.
This is designing the failure state first applied to the failure that is deliberate. A refusal isn't the model being wrong. It's the product working exactly as specified and declining to say so.
Related: design the failure state first, undo over confirm, regeneration is an edit, the Poppy build, and how I work.
The three sources above were read on 5 October 2026.