From 03a5124335bc54aa355919e7081d965666571178 Mon Sep 17 00:00:00 2001 From: edoch Date: Tue, 17 Mar 2026 01:33:27 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20fix=20nullable=20description=20?= =?UTF-8?q?=E2=80=94=20all=20four=20checks=20are=20independent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- book/src/concepts/validation.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/book/src/concepts/validation.md b/book/src/concepts/validation.md index 212bfa8..200f05c 100644 --- a/book/src/concepts/validation.md +++ b/book/src/concepts/validation.md @@ -49,7 +49,14 @@ Objects just check that the value is an object — individual keys are not valid Null interacts with validation in specific ways: -**Null values skip type and allowed checks.** If a field's value is `null`, it doesn't matter what type is declared or which paths are allowed — those checks are skipped entirely. Only the nullable constraint applies. +**All four checks are independent.** A null value is checked like any other value — each violation type is evaluated separately: + +- **`WrongType`** — null is accepted by any type, so this never fires on null. +- **`Disallowed`** — the field is present (the key exists), so `Disallowed` fires if the path isn't in `allowed`. +- **`MissingRequired`** — null counts as "present", so this never fires on null. +- **`NullNotAllowed`** — fires when the value is null and `nullable = false`. + +A single null field can trigger both `Disallowed` and `NullNotAllowed` at the same time. **Null vs absent.** These are different situations with different outcomes: @@ -59,7 +66,7 @@ Null interacts with validation in specific ways: | Field is **null**, `nullable = true` | `drift_rate: null` | Passes | | Field is **null**, `nullable = false` | `drift_rate: null` | `NullNotAllowed` | -A null value counts as "present" — the field exists in the frontmatter, it just has no value. So null never triggers `MissingRequired`. An absent field is genuinely missing — it can trigger `MissingRequired` but never `NullNotAllowed`. +A null value counts as "present" — the field key exists in the frontmatter, it just has no value. So null never triggers `MissingRequired`. An absent field is genuinely missing — it can trigger `MissingRequired` but never `NullNotAllowed`. > **Note:** In YAML, unquoted `null` is a null value, not the string `"null"`. To store the literal string, write `drift_rate: "null"` (with quotes).