Skip to main content
Lesson 3 of 12 · Structured JSON Outputs

Unsupported types and limitations

Lesson 3 of 12 Updated July 30, 2026 Developer
On this page
  1. What schemas can’t do
  2. The three major restrictions
  3. Other limitations to know
  4. The strategy: schema + prompt
  5. Key takeaways

What schemas can’t do

Understanding the limits of structured outputs is just as important as mastering their capabilities. The Grok API doesn’t support certain JSON Schema constraints. Trying to use them will trigger an error or cause unexpected behavior.

The three major restrictions

allOf — composition not allowed

In JSON Schema, the allOf keyword combines multiple subschemas that an object must satisfy simultaneously. The Grok API does not support this feature.

// DOES NOT WORK
{
  "allOf": [
    { "properties": { "nom": { "type": "string" } } },
    { "properties": { "age": { "type": "number" } } }
  ]
}

Alternative: use a single object with all properties:

// WORKS
{
  "type": "object",
  "properties": {
    "nom": { "type": "string" },
    "age": { "type": "number" }
  }
}

minLength / maxLength — no string length constraints

You can’t force the model to produce a string with a minimum or maximum length.

// DOES NOT WORK
{
  "properties": {
    "code": {
      "type": "string",
      "minLength": 3,
      "maxLength": 10
    }
  }
}

Alternative: specify the constraint in the prompt instead of the schema:

messages=[{
    "role": "user",
    "content": "Generate a product code between 3 and 10 characters."
}]

The model will follow the instruction in most cases, but it isn’t guaranteed like a schema constraint would be.

minItems / maxItems — no array size constraints

You can’t enforce a minimum or maximum number of elements in an array.

// DOES NOT WORK
{
  "properties": {
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "maxItems": 5
    }
  }
}

Alternative: use the prompt to guide the model:

messages=[{
    "role": "user",
    "content": "List between 1 and 5 relevant tags for this article."
}]

Other limitations to know

No regex patterns

The API doesn’t support pattern constraints on strings. You can’t enforce an email format, UUID, or phone number via the schema.

// DOES NOT WORK
{
  "properties": {
    "email": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$"
    }
  }
}

No default values

The default keyword has no effect. If a field is in the schema, the model will always populate it.

No conditionals

The JSON Schema keywords if, then, and else aren’t available.

The strategy: schema + prompt

The best approach combines both:

  1. The schema guarantees the structure: field names, types, nesting
  2. The prompt guides the content: lengths, specific formats, business rules
class Report(BaseModel):
    title: str
    summary: str
    key_points: list[str]
    score: float
    category: str

messages=[{
    "role": "user",
    "content": """Analyze this text and produce a report.
    - The summary must be 2-3 sentences.
    - List exactly 5 key points.
    - The score is between 0 and 10.
    - Category among: positive, negative, neutral."""
}]

The schema guarantees types and structure. The prompt controls values and content constraints.

Key takeaways

  • allOf, minLength, maxLength, minItems, and maxItems are not supported
  • pattern, default, and if/then/else constraints aren’t supported either
  • Use anyOf instead of allOf when possible
  • Offload content constraints to the prompt
  • Combining schema (structure) + prompt (content) is the optimal strategy