Consider a website builder turning a bakery owner’s notes into an opening-hours panel. The owner writes, “Saturday: 9 a.m. to noon. We haven’t decided our Sunday hours.” The builder returns a tidy object with Saturday hours and matching Sunday hours. The page renderer accepts it. A visitor could now plan a Sunday trip on the strength of an invented opening time.
The object can pass its schema while misrepresenting the source. A schema describes which values software can accept. Evidence determines which values the source supports. Separating schema validation from source support helps identify which check failed.
What the schema checks
JSON is a text format that software can read as named fields and values. A schema adds rules about those fields: which must appear, what types they contain, and which extra fields are allowed. The JSON Schema object reference explains the roles of properties, required and additionalProperties. Listing a field under properties does not, by itself, make that field required.
Suppose the bakery builder requires saturday_hours and sunday_hours, both strings, and rejects extra fields. This response fits:
{
"saturday_hours": "09:00-12:00",
"sunday_hours": "09:00-12:00"
}
Both fields exist. Both values are strings. There is nothing else in the object. The Sunday value still contradicts the owner’s uncertainty. A validator given just this object and that schema has no copy of the note against which to check it.
A provider’s structured-output mode can help produce the expected shape. Anthropic’s structured-output documentation, for example, describes constraining generation to a supported schema. Its documented exceptions include refusals and responses stopped at the token limit. An application still needs to handle those completion states before accepting a result.
Unknown needs a place in the data
The initial design gives the extractor two required strings and gives the renderer two things to display. It has no agreed representation for “the owner hasn’t supplied this.” A prompt asking for accuracy leaves that design problem unresolved.
For this example, the product could define null as “hours not established by the supplied note.” JSON Schema permits a field to accept more than one type, using a rule such as "type": ["string", "null"], as its type reference explains. With that rule, a faithful extraction is:
{
"saturday_hours": "09:00-12:00",
"sunday_hours": null
}
The renderer then needs a deliberate behavior for that value. It might leave Sunday off the draft panel and ask the owner to complete it before publishing. Showing “Closed” would add another unsupported claim: undecided hours do not establish that the bakery is closed.
Missing, unknown and closed can deserve different states in a fuller product. If the editor needs to distinguish an omitted day from an explicitly undecided one, a single nullable string will lose information. The data needs separate states for that distinction.
Evidence has to connect a value to its source
One useful extraction design returns the supporting text with each asserted value. Saturday’s hours could carry the quote “Saturday: 9 a.m. to noon.” Sunday could carry the sentence about the undecided hours and remain unset. The supporting text would remain available for review in the editor.
A separate check can establish whether the returned quote occurs in the supplied note. That catches a fabricated quotation, but an exact text match establishes only that the words are present. A quote about Saturday would still be the wrong support for Sunday. The value, its subject and the cited passage need to agree.
For a small opening-hours editor, some checks can be ordinary code. The day named in the passage can be compared with the day receiving the value, and a parser can check the time range. Ambiguous language, such as “same as last weekend,” needs context the note may not contain. In that case, leaving the value unresolved preserves a question the owner can answer.
Adding another model to assess support creates another judgment to evaluate. It can be useful, particularly for varied natural language, but agreement between two generated answers does not establish what the owner meant. A reviewable passage and a clear unresolved state give the application somewhere to put uncertainty.
Different failures need different repairs
| Check | Question answered | Example repair |
|---|---|---|
| JSON parsing | Can software read the response? | Handle the incomplete response. |
| Schema validation | Are required fields and allowed types present? | Correct the output contract or generation settings. |
| Source support | Does the note establish this day’s hours? | Leave Sunday unresolved and request its hours. |
| Publishing behavior | Does the page display unresolved hours appropriately? | Keep the incomplete panel in the editor. |
These checks also make failure counts more useful. A string in the wrong format points toward the output contract. A perfectly formatted Sunday guess points toward extraction and uncertainty handling. Retrying both failures with “return valid JSON” treats them as the same problem and leaves the source-support error unexplained.
A compact test set for this feature could contain an explicit opening time, explicitly undecided hours, a declared closure, and a note that says nothing about Sunday. The expected result would specify both the extracted state and what the page may display. Those cases test the distinction that caused the mistake without needing a large benchmark.
Before connecting structured output to a published page, choose one required field and ask what should happen when its source says nothing. Give that answer a representation in the data, then check the resulting display. For the bakery, a valid object becomes useful when its Sunday field preserves the owner’s uncertainty.