Skip to main content
Enums are the strongest constraint for categorical fields: the output must match one of the listed values exactly. But real-world taxonomies drift. A new product launches, a new issue type appears, and suddenly a significant fraction of inputs don’t fit any existing category. If your enum has no escape hatch, the model is forced to pick the closest match, which introduces silent misclassification. The fallback pattern adds an "other" value and models it as a separate union branch that requires a freeform description. This preserves the analytical benefits of a closed enum for known categories while capturing novel ones accurately.

Use case

Issue triage where most tickets fit known categories (billing, technical, account, shipping), but some do not, and you need to capture what they actually are instead of forcing a bad fit.

Schema pattern

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "issue_type": {
          "type": "string",
          "enum": ["billing", "technical", "account", "shipping"]
        }
      },
      "required": ["issue_type"],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "issue_type": { "type": "string", "const": "other" },
        "other_issue_type": { "type": "string", "minLength": 3, "maxLength": 60 }
      },
      "required": ["issue_type", "other_issue_type"],
      "additionalProperties": false
    }
  ]
}

Example outputs

Known category:
{
  "issue_type": "technical"
}
Fallback category:
{
  "issue_type": "other",
  "other_issue_type": "partner-api-timeout"
}

Why this works

For the vast majority of inputs, issue_type is one of the four known values. Your analytics dashboards, routing rules, and reports all work unchanged. When a genuinely novel category appears, the model selects "other" and the second oneOf branch requires other_issue_type, a bounded freeform string that captures what the issue actually is. This gives you the best of both worlds: a closed enum for known categories (fast aggregation, reliable routing) and a structured escape hatch for new ones (no data loss, easy to review). Over time, you can promote frequently-seen other_issue_type values into the main enum.