WHAT YOU WILL BUILD
A validator that separates parsing from type, range, and allowed-field checks.
JSON syntax only tells you whether a payload can be parsed. An application also needs a contract: required fields, types, ranges, and how extra fields are handled. A well-formed answer can still contain false facts.
Before you start
Use a text editor and Node.js 22 or newer ↗. Check your version with node --version. Save the downloaded file in an empty folder, then open a terminal in that folder.
All data is included. No packages, account, or API key are required. The sample validator covers one small contract. It is not a full JSON Schema implementation or an LLM response generator.
Download the lab (.mjs)FOLLOW ALONG
Work through the example.
- 01
Define the contract
Accept exactly two fields: answer as a string up to 200 characters and days as an integer from 0 to 365. In this exercise, unknown values must follow a separate application path.
- 02
Run all four responses
Only the first response passes. The others contain a string where an integer is expected, an unexpected execute field, or prose outside the JSON.
- 03
Add boundary cases
Test null, an array, days=-1, days=366, and a 201-character answer. Add explicit expected failures for each input rather than relying on the four original cases.
- 04
Check meaning after structure
Change a valid response to days=90. It passes this contract but contradicts the sample 30-day policy. Keep a separate evidence or business-rule check before using the value.
THE COMPLETE LAB
Run it locally.
Run this command from the folder containing your downloaded file:
node prompt-structured-output.mjsView or copy the complete JavaScript
// SaveMyToken local lab. Run with Node.js 22 or newer.
import assert from "node:assert/strict";
function validate(raw) {
try {
const value = JSON.parse(raw);
return value !== null && typeof value === "object" && !Array.isArray(value)
&& Object.keys(value).length === 2
&& typeof value.answer === "string" && value.answer.length <= 200
&& Number.isInteger(value.days) && value.days >= 0 && value.days <= 365;
} catch { return false; }
}
const inputs = [
'{"answer":"Unused items only","days":30}',
'{"answer":"Unused items only","days":"30"}',
'{"answer":"Unused items only","days":30,"execute":"refund"}',
'Here is your JSON: {"days":30}',
];
const results = inputs.map(validate);
assert.deepEqual(results, [true, false, false, false]);
console.log("Valid responses:", results.join(", "));
Expected output for the unchanged example
Valid responses: true, false, false, falseThe assertions also check the baseline behavior. After changing an input, predict the result and update the relevant assertion.
NOW CHANGE ONE THING
Make the example your own.
Extend the contract with a status field and permit days=null only when status is unknown. Update both successful and failing cases before changing the validator.
You are done when…
The baseline prints true, false, false, false, and you can distinguish a parse failure, a contract failure, and a factual failure.
If something goes wrong
Avoid repairing arbitrary output with a regular expression and assuming it is safe. For a growing contract, use a maintained schema validator and bound any retry or repair step.
EXPLAIN WHAT YOU LEARNED
Interview practice
Try answering aloud before opening the reference answer. These are original learning questions, not a record of any employer's interviews.
01Is valid JSON sufficient for an application?
No. Check the expected shape, required fields, types, values, and business rules after parsing. Apply separate authorization to any requested action.
Watch for: A JSON object may be syntactically valid and completely unsuitable for the task.
02What should happen to unexpected fields?
Choose an explicit policy. This lab rejects them so a hidden execute field cannot silently become part of downstream behavior.
Watch for: Ignoring unknown fields in one layer while acting on them in another creates inconsistent rules.
03How should missing information be represented?
Define an explicit unknown state, such as a status plus nullable value, and validate the relationship between fields. Do not replace unknown numbers with zero.
Watch for: An empty string can hide the difference between missing and deliberately blank data.
04Does structured output guarantee factual accuracy?
No. It constrains representation. Compare the content with evidence, application invariants, or task-specific tests before treating it as correct.
Watch for: A schema-valid 90-day return window can still contradict a 30-day policy.
05How should an application handle validation failure?
Return a clear failure or try a bounded repair with the validation feedback. Preserve the failed payload for appropriate diagnostics and stop when the retry budget ends.
Watch for: Unlimited repair attempts can multiply cost without improving correctness.
Sources and further reading
The explanation and local exercises were written for SaveMyToken. These references support the underlying concepts; the sample outputs describe only the supplied examples.
JSON Schema: object validation ↗