Most misunderstood keywords {#misunderstood-jsonschema}#
# Most Commonly Misunderstood Keywords in JSON Schema
JSON Schema is powerful but nuanced. Many keywords behave differently than developers expect, especially across drafts. This page highlights the most commonly misunderstood keywords, their pitfalls, and corrected usage.
---
### `type`
- **Problem:** Developers often assume `type` can only be a single string. In fact, it can be a union of multiple types.
- **Correct:**
~~~yaml
type: [string, "null"]
~~~
---
### `nullable`
- **Problem:** Some expect `nullable` like in OpenAPI 3.0, but **it does not exist in JSON Schema**.
- **Correct:** Use a union with `"null"`.
~~~yaml
type: [object, "null"]
~~~
---
### `additionalProperties`
- **Problem:** Many think it defaults to `false`. In JSON Schema, it defaults to **true** — meaning extra keys are allowed unless explicitly disallowed.
- **Correct:**
~~~yaml
type: object
properties:
id:
type: string
additionalProperties: false
~~~
---
### `unevaluatedProperties`
- **Problem:** Confused with `additionalProperties`.
- `additionalProperties`: applies when no other schema matches.
- `unevaluatedProperties`: applies *after* all other keywords are processed (2019-09+).
- **Correct:**
~~~yaml
unevaluatedProperties: false
~~~
---
### `required`
- **Problem:** Developers sometimes add `required: true` at the property level. Incorrect — `required` must be an array at the object level.
- **Correct:**
~~~yaml
type: object
properties:
name:
type: string
required: ["name"]
~~~
---
### `default`
- **Problem:** Assumed to be enforced by validators. In reality, `default` is **annotation only** — used by tools, not validation.
- **Correct:**
~~~yaml
type: string
default: "guest"
~~~
---
### `enum` vs `const`
- **Problem:** Developers overuse `enum` when only one value is allowed.
- **Correct:**
~~~yaml
enum: ["red", "green", "blue"] # multiple values
const: "red" # single value
~~~
---
### `format`
- **Problem:** Assumed to always validate strictly. Actually, it’s **informative**, and enforcement varies by validator.
- **Correct:**
~~~yaml
type: string
format: email # may or may not be enforced depending on validator
~~~
---
### `pattern`
- **Problem:** Regex flavor confusion. JSON Schema uses **ECMA-262 (JavaScript)** regex, not PCRE. Some developers mistakenly use anchors incorrectly.
- **Correct:**
~~~yaml
type: string
pattern: "^[A-Za-z0-9_-]{3,16}$"
~~~
---
### `items`
- **Problem:** Often misused for tuples.
- Single schema → applies to all array elements.
- Array of schemas → tuple validation.
- **Correct:**
~~~yaml
items:
- type: string # first element
- type: number # second element
~~~
---
### `exclusiveMinimum` / `exclusiveMaximum`
- **Problem:** In draft-07, they were booleans paired with `minimum`/`maximum`. In 2019-09+, they are standalone numeric values.
- **Correct (2020-12):**
~~~yaml
exclusiveMinimum: 0
exclusiveMaximum: 100
~~~
---
### `dependencies` vs `dependentRequired` / `dependentSchemas`
- **Problem:** Developers still use `dependencies` (deprecated in 2019-09).
- **Correct:** Use `dependentRequired` or `dependentSchemas`.
~~~yaml
dependentRequired:
password: ["passwordConfirmation"]
~~~
---
### `$ref`
- **Problem:** Many add siblings like `type` or `description` alongside `$ref`. JSON Schema does **not** allow this — `$ref` replaces the whole object.
- **Correct:**
~~~yaml
$ref: '#/$defs/User'
~~~
---
### `$defs` vs `definitions`
- **Problem:** `definitions` is old (draft-07). Newer drafts use `$defs`. Some tools still expect `definitions`.
- **Correct:**
~~~yaml
$defs:
Address:
type: object
properties:
street:
type: string
~~~
---
### `not`
- **Problem:** Misinterpreted as meaning "exclude this property." Actually, `not` excludes *schemas*.
- **Correct:**
~~~yaml
not:
type: string
~~~
---
### `title` and `description`
- **Problem:** Assumed to affect validation. They don’t — these are **annotations only** for humans/tools.
- **Correct:**
~~~yaml
title: "User Schema"
description: "Represents a system user"
~~~