F6.2 F6

required, nullable, and enum: Schema Features That Shape Output

Three schema features control what the model is allowed to output: required controls which fields must appear, nullable types control whether fields can be null, and enum constrains values to a fixed set. Getting these right prevents fabrication and ensures clean data.

required: presence control

The required array at the object level lists field names that must be present. Everything in properties but NOT in required is optional — it may or may not appear in the output.

Properties are optional by default. There is no optional: true flag on individual properties. No separate optional array. Optionality is determined solely by the required array.

Nullable: explicit “not available”

A nullable field uses a union type: "type": ["string", "null"]. This means the field can be a string OR null. It gives the model a legitimate way to say “this information doesn’t exist” without fabricating a value.

There is no nullable: true keyword in standard JSON Schema (that’s OpenAPI, not JSON Schema). No "type": "string?" shorthand. The union array ["string", "null"] is the correct syntax.

required vs nullable: different things

  • Not required = the field can be absent (key doesn’t exist in the output)
  • Nullable = the field is present but its value is null

{} (field absent) is different from {"field": null} (field present, value is null). For extraction, nullable + not required gives maximum flexibility: the model can include the field with data, include it with null, or omit it entirely.

The anti-pattern: making a possibly-absent field required with type string. The model is forced to produce some string — so it fabricates. Make it nullable instead: "type": ["string", "null"], not in required. Now the model returns null when the information genuinely isn’t there.

enum: value restriction

enum constrains a field to a fixed set of values: "enum": ["invoice", "contract", "receipt"]. Only these exact values are valid.

Contrary to intuition, JSON Schema enum can contain mixed types — ["low", 1, "high", null] is valid. But combining enum with type restricts both: "type": "string", "enum": ["active", "inactive"] ensures only these two strings are accepted.

A useful pattern: add an "other" escape hatch to enums (["invoice", "contract", "receipt", "other"]) with a companion detail field. This handles unexpected categories without forcing the model to misclassify into the closest-but-wrong category.


One-liner: required controls field presence (optional by default), nullable ["type", "null"] prevents fabrication for missing data, and enum with an “other” escape handles unexpected categories gracefully.