Build1 publisher3 min readPublished
A planning step asked for entities and got a bare array that JSON.parse waved straight through. The repair needed both a schema in the prompt and a wrapper in the parser, because two of the three backends behind the interface can only ask.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The sneaky part of a schema failure is where it lands. A parse failure fails at the parse call [4]. A wrong shape clears that gate, and a well-formed object travels on until something downstream reads a field that was never there, far from where the problem was born [6]. This pipeline caught it early only because Zod sat at the boundary and rejected the object JSON.parse had already accepted [3].
The commit that closed the incident did two things, and they are not redundant. Putting the literal schema in the prompt lowers the rate at which the model deviates [7]. Wrapping a bare top-level array in the expected envelope handles the deviation already observed, in code, every time [7]. Jula Markova, who writes at dev.to that she is an IT analyst rather than a software engineer by training [15], puts it as reducing the error rate with the prompt and making the residual error harmless with the fallback [8]. The prompt lowers how often the model deviates; the fallback routes any deviation that still happens into a branch someone wrote.
What turns that from a patch into a design rule is the runner interface. Every AI call goes through one interface, with three interchangeable backends behind it and a flag to swap them: the Claude CLI on a subscription, the Claude Agent SDK on an API key, and codex, GPT-5.5, through a ChatGPT subscription [10][11]. Only the SDK converts the Zod schema to JSON Schema and sends it as an output format, so the response cannot arrive in the wrong shape [12]. The CLI carries the schema in the prompt and returns free text, which the code then cuts the JSON out of and validates after the fact [13]. Two of the three can therefore only ask the model for the right shape rather than enforce it [1], and the shared prompt has to be correct on the weakest of them, so enforcement can sit on top of the extract-and-validate path but cannot delete it.
codex is the more interesting refusal. It has an output-schema mode, but according to Markova that mode rejects schemas containing references, and an ordinary Zod schema converted to JSON Schema produces exactly those; strict-mode constraints rule out the rest of her real schemas [14]. codex's output-schema mode exists in the product, but this pipeline cannot reach it.
Before borrowing the SDK's guarantee, test your schema graph, not a benchmark. For "cannot arrive in the wrong shape" to transfer, your schemas have to survive conversion into the subset the provider accepts [12], and you keep validating anyway, because the guarantee is about shape and the taxonomy that produced it stops at shape [4][12].
The house rule that came out of the incident is written twice, word for word, once in global rules and once in project rules [9]. Markova calls the duplication deliberate emphasis [9]. It is the version-controlled equivalent of writing it on the back of your hand.
The portable contract on this evidence is narrow: schema in the prompt, extract, validate at the boundary, one deterministic repair per known deviation. Treating API-layer enforcement as the design assumption is how the other two backends fail without saying so [13][14].
Ranked by verification strength, evidence, and original report placement.
codex actively refuses native enforcement: it has an output-schema mode, but that mode rejects schemas with references, and ordinary Zod schemas converted to JSON Schema produce exactly those, while its strict-mode constraints are violated by the author's real schemas; the post then states the codex backend fell back to the same technique, with the published text breaking off mid-sentence.
On March 3rd, 2026, a planning step in a content pipeline asked the model for a list of entities and received exactly what it asked for in valid JSON, which was the problem.
The model returned a bare top-level array of entity strings; the code expected an envelope object of the form { "entities": [...] }.
JSON.parse accepted the bare array without complaint, and the failure surfaced one layer later in Zod validation, which knew the shape was wrong even though the syntax was fine.
The author separates two failure layers that need separate defenses: parse failure, where the text is not valid JSON at all (markdown fences, a chatty preamble, a truncated tail), and schema failure, where the JSON is valid but the shape is wrong (bare array instead of envelope, missing field, string where a number should be).
According to the author, "ask for JSON" only addresses layer one, and only optimistically.
Follow any of these and your For You feed starts watching them — no settings page required.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
First-hand, single witness
The detail here is the kind you only have if you were there: both JSON shapes quoted, a dated incident, the two halves of the commit that closed it, the same rule sentence copied into two config layers. That part is convincing. The two findings that give the story its reach are behaviours of other companies' tooling, reported without a version, an error string or a date, and the published text stops mid-sentence while the author is still setting out her conditions.
One pipeline, one team
What is deployed is a single content pipeline with three swappable backends, plus a rule written into that project's global and local configuration. The record is real and dated, but it covers only the author's own work. No other team is reported following the schema-in-prompt rule, and the March failure is the only incident on the record.
Title outruns the sample
The writing is more careful than its framing. Only one of three backends refuses a wrongly shaped response given the author's schemas, and the reason is narrow: her converted Zod schemas contain references, which the codex output-schema mode will not take. She says so plainly and gives the opposing case for native structured output a fair hearing. Read as a general ranking of what three vendors can enforce, the conclusion is wider than the one pipeline it came from.
Own project, no vendor stake disclosed
The pipeline being praised and criticised publishes to bestaiweb.ai, so the author is writing up her own product on a platform where technical posts buy reputation. No relationship with either model vendor is disclosed, and the comparison is unflattering to the subscription backend she uses by default, which cuts against a promotional read. The pull that remains is towards presenting one project's config decision as a general lesson.
Credible but uncorroborated
We can be reasonably sure what the code does, since the author is describing her own repository and quotes the shapes and the fix. Confidence falls on the part that travels furthest, namely what each vendor interface can enforce right now. One account, no versions, and a piece that ends before completing its own concession puts this in read-and-verify territory rather than settled.
build
117 identical errors, zero bugs: when the defect lives in the orchestration1 publisher
build
Before you buy another GPU, check num_ctx and the rope base1 publisher
build
Invoked in three runs, executed in none: the cost rule that never got asked1 publisher
build
An empty MCP tool list is a successful response, and the bug is on the server side1 publisher
Publishers with included, body-backed reporting in this cluster.
1 article · September 8, 2026