``You're calling OpenAI from Node.js. 99% of requests work. Then randomly:
BadRequestError: 400 could not parse JSON body
Or:
SyntaxError: Invalid JSON: EOF while parsing an object
Or, if you're using tool calling:
Invalid JSON in tool call arguments
You check your code. Nothing changed. You retry manually — it works. You deploy again. It breaks again.
These errors are NOT your bugs. They're transient artifacts from:
Every one of these is intermittent. So you can't debug it with a stack trace. You just suffer.
People usually do this:
try {
const res = await client.chat.completions.create({...});
} catch (e) {
const res = await client.chat.completions.create({...});
}
Problems:
Different errors need different handling:
| Error | Correct action |
|---|---|
| Transient 400 (could not parse JSON body) | Retry with backoff + jitter |
| Truncated stream (EOF while parsing) | Retry, possibly with higher max_tokens |
| Malformed tool args | Sanitize inline, no retry needed |
| Invalid API key | Fail fast, do NOT retry |
| Rate limit | Retry with longer backoff |
Doing this manually is ~150 lines of code you'll write badly. Or:
npm install @coder12-z/llm-shield
import { shield } from "@coder12-z/llm-shield";
import OpenAI from "openai";
const client = new OpenAI();
const safeCall = shield(async (prompt) =>
client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: prompt }],
response_format: { type: "json_object" },
}),
{
maxRetries: 3,
onRetry: ({ attempt, kind }) => console.log(`retry #${attempt} (${kind})`),
}
);
Three lines of config. Zero dependencies. Works with OpenAI, Anthropic, Gemini, or anything that throws Error objects with status and message.
MIT licensed. Feedback welcome.