Lessons · LLM06: Unbounded Consumption · warning
Close the tab and the model keeps generating, and you keep paying.
Caught by streaming-response-without-abort-handling · CWE-400, CWE-770
Your route streams the model's reply back to the browser, but it never tells the model call when the browser goes away.
When the user closes the tab or navigates away, the connection drops. The model call does not know, so it keeps generating to the end, and every token is billed.
In development nobody disconnects mid-reply, so this never shows up until the bill does.
Your chat route uses streamText with a long maximum output.
export async function POST(req: Request) {
const { prompt } = await req.json();
return streamText({ model, prompt }).toTextStreamResponse();
}
The cost: A large provider bill, or hitting your rate limit so real users get errors.
Paste this into Claude Code, Cursor, or whatever wrote the code. When llm-audit finds the mistake in your project, npx llm-audit prompt gives you the same prompt with every file and line filled in.
Fix this in my project: a streaming model call does not stop when the client disconnects.
Please:
1. Pass the request's abort signal to the model call: abortSignal: req.signal for the AI SDK, or { signal: req.signal } for the OpenAI and Anthropic SDKs.
2. Set a sensible maximum output length for this endpoint.
3. Add rate limiting per user or per IP.
Show me the diff.A prompt that looks for the same mistake everywhere else, without changing anything yet.
Check this project's streaming AI endpoints for runaway cost, before I ship it.
Look for:
- Streaming model calls (streamText, streamObject, stream: true) that do not receive the request's abort signal.
- Model calls with no maximum output length.
- AI endpoints with no rate limiting or authentication.
For each one, give me the file and line and estimate what one request costs if the client disconnects immediately. Do not change any code yet.npx llm-audit scan
Runs on your machine with Semgrep. Nothing is uploaded.