Null vs Missing Request Fields: Keep 2 Contract Axes Separate

TakeawayDetail
Presence and value acceptance are separate contract decisions.The codegenes.net validation guide describes a field that must be present but can be null: requiring a property does not, by itself, prohibit null.
Use required to specify property presence.The w3tutorials.net OpenAPI tutorial identifies required as the mechanism for requiring fields and describes omission from required as implicit optionality.
Diagnose missing-field and null-value failures separately.The codegenes.net guide distinguishes failure caused by omitting a required field from a “Field may not be null” error caused by submitting a prohibited null value.
Do not let explanatory prose merge the rules.The codegenes.net guide defines optional as allowing omission or explicit null, conflating presence with value acceptance; documentation should state each permission independently.

The w3tutorials.net OpenAPI tutorial puts a consequential default in a heading: “Fields Are Optional by Default.” Yet optional does not mean that every apparently empty request is interchangeable. The bodies {} and {"name":null} communicate different things: the former omits name; the latter supplies it with an explicit null value. A contract can accept either, accept both, or reject both, depending on its separate presence and value rules.

The required keyword addresses whether a property must appear. The property's value constraints address whether null is accepted when it does appear. The codegenes.net validation guide makes the distinction concrete with a field that must be present but can be null. But that same guide also describes optional fields as allowing omission or explicit null—a wording choice that collapses the distinction readers need.

That collapse is a structured-authoring failure, not merely a vocabulary problem. A definitive reference must keep schema declarations, explanations, and examples aligned: may name be omitted, and may its supplied value be null? AI-generated summaries must preserve those answers separately. Documentation must also state any application behavior attached to omission or explicit null rather than treating validation permission as an instruction to clear, preserve, or default a value.

Null vs Missing Request Fields

Separate 2 Contract Axes

A mandatory property can accept null without accepting omission. Those are different contract decisions, not competing meanings of “required.” For displayName, “must be supplied” answers whether the member must exist; “accepted values” answers what its value may be. A reference page that preserves only one answer cannot faithfully describe the request.

According to the OpenAPI 3.1.0 specification’s Schema Object definition, its schema vocabulary aligns with JSON Schema Draft 2020-12. The declaration type: ["string", "null"] admits string values and the JSON null value. An omitted displayName is neither: there is no value instance for that property’s schema to validate. Its absence must therefore be evaluated through the enclosing object’s presence constraints, not through the property’s type declaration.

The nesting is part of the meaning. This schema requires displayName while admitting explicit null: {"type": "object", "required": ["displayName"], "properties": {"displayName": {"type": ["string", "null"]}}}. The object’s required array names the member whose presence is mandatory; properties.displayName.type constrains that member’s value when present. Documentation that flattens these locations into an undifferentiated list of attributes loses the distinction between the constraint’s owner and its target.

Putting required: true inside the displayName schema is not equivalent syntax. JSON Schema’s required keyword takes an array of property names and constrains an object instance; it is not a Boolean flag attached to the property being required. Likewise, setting nullable: true does not make a property optional and null-capable in OpenAPI 3.1. Use the enclosing required array for presence and a type union containing "null" for null acceptance, not the legacy nullable keyword.

Body presence adds a separate documentation boundary. According to OpenAPI’s Request Body Object definition, requestBody.required determines whether the HTTP request body itself must be supplied. It does not require every member inside that body. A required JSON body can still accept {} when its object schema has no mandatory properties or other constraints rejecting that object. Generated references consequently need distinct labels such as “Request body: required” and “displayName must be supplied: no.”

From a structured-authoring perspective, I would store “must be supplied” and “accepted values” as independent documentation fields rather than derive both from the adjective “nullable.” That adjective cannot distinguish an omittable string-or-null property from a mandatory string-or-null property. The independent fields win because they preserve enough information to reconstruct both schema decisions. Before publishing, verify that each property’s labels select exactly one row below. These outcomes assume the displayed presence and type constraints without additional validation restrictions.

ContractEnclosing object’s required arrayproperties.displayName.type{}{"displayName": null}{"displayName": "Brady"}
Optional, non-nullAbsent or excludes "displayName""string"AcceptedRejectedAccepted
Optional, null-capableAbsent or excludes "displayName"["string", "null"]AcceptedAcceptedAccepted
Mandatory, non-nullIncludes "displayName""string"RejectedRejectedAccepted
Mandatory, null-capableIncludes "displayName"["string", "null"]RejectedAcceptedAccepted
Perpendicular stone corridors enclosed empty chamber along axis
Perpendicular stone corridors enclosed empty chamber along axis

Read the Primary Sources

Copied OpenAPI 3.0-era examples are a concrete source of misleading OpenAPI 3.1 documentation: they can preserve valid-looking syntax while importing the wrong validation semantics. The decisive evidence is the specification version that defines a keyword, not whether a documentation renderer displays it. A source audit therefore needs to distinguish the JSON data model, JSON Schema validation rules, and historical OpenAPI behavior.

According to the JSON specification, Sections 1 and 3, JSON has six value alternatives: object, array, number, string, boolean, and null. The literals true and false belong to the boolean category. Missing is neither another JSON value nor a token clients can transmit. For example, {} contains no member named displayName, whereas {"displayName":null} contains that member with a JSON value. This is a distinction in the transmitted document, before any schema evaluates it.

According to JSON Schema Validation, Section 6.1.1, the seven permitted type-name strings are null, boolean, object, array, number, string, and integer. There is no conflict with JSON’s value categories: integer is a validation distinction within JSON numbers, covering numbers with a zero fractional part. It does not introduce an additional wire-format category. That same section permits an array of type names and specifies that matching any listed type satisfies the type constraint—the normative basis for admitting null through a type union.

According to OpenAPI 3.0.3, Section 4.7.24.2, nullable defaults to false. Setting it to true adds null to the allowed type only when type is explicitly defined in the same Schema Object; other constraints can still disallow null. Even historically, nullable was not an instruction to make a property optional. Carrying nullable: true into a 3.1 example therefore does not establish either optional presence or permission for explicit null. The historical definition explains the migration trap; it is not authority for current semantics.

According to JSON Schema Core, Section 4.3.1, unrecognized keywords SHOULD be treated as annotations. That wording matters: accepting a schema containing a legacy keyword is not proof that the keyword participates in validation. A loader may accept nullable without assigning it assertion behavior. Any implementation-specific interpretation would need separate evidence; successful loading alone cannot establish the request contract.

Following Brady Weaver’s documentation-research approach, classify the ledger below as normative language facts and their direct implications—not product benchmarks or measured reader-comprehension results. For each inherited example, attach the governing version and clause to its semantic claim. This makes a version mismatch visible before polished documentation turns it into an apparently authoritative rule.

Claim to auditPrimary document and specification versionSectionVerification task
Missing is not a JSON value.JSON specification, Internet Standard1 and 3Check the value grammar rather than treating omission as a literal.
Integer refines numbers; type arrays admit alternatives.JSON Schema Validation, draft-bhutton-json-schema-validation-016.1.1Check allowed type names and union semantics.
Legacy nullable has a false default and a same-object type precondition.OpenAPI Specification 3.0.34.7.24.2Flag copied examples whose authority stops at this version.
Keyword acceptance does not establish validation behavior.JSON Schema Core, draft-bhutton-json-schema-014.3.1Separate annotation handling from demonstrated assertion semantics.
grassland null

Choose the Documentation Pattern

A state table backed by schema and executable fixtures wins because it makes each request-field claim independently checkable. The decisive advantage is not brevity: it is the ability to expose disagreement between what consumers read and what validation accepts. A fluent explanation or successful example cannot provide that coverage alone.

ApproachSeparates presence from value?Supports automated conformance checks?Decision
State table backed by schema and fixturesYesYes, when wired into CIWinner
Prose-only 'nullable' labelNoNoReject as the sole contract
Single successful request exampleNoOnly for the illustrated requestSupplement only

Define the winning table’s columns as input condition, expected validation result, application interpretation, and linked fixture identifier. The input condition must distinguish omission from explicit null; the validation column records acceptance or rejection; the interpretation column states what an accepted request means; and the identifier connects that promise to an executable fixture. Require a separate row for every behavior the endpoint’s documentation promises, including rejected inputs.

For example, suppose a hypothetical Account API promises that omitting nickname preserves its existing value, while supplying null clears it. Give those promises separate rows linked to account-nickname-omitted and account-nickname-null fixtures. Both rows may say “accepted,” but their application interpretations differ. An acceptance-only fixture cannot substantiate the clearing promise: the linked executable check must also verify the documented application outcome.

Use the schema as the validation contract behind those rows: the enclosing object’s required array governs mandatory presence, and the property’s type union includes "null" only when permitted. Do not approve a “nullable” label backed merely by nullable: true; that legacy keyword does not establish either optionality or null acceptance in OpenAPI 3.1.

The publication threshold is zero contradictions among schema, state table, and executable fixtures. If the table accepts an input that the schema rejects—or a fixture expects rejection where the table promises acceptance—the page is internally inconsistent. Do not ask readers to infer precedence. Reconcile the artifacts before publication, and wire fixtures into CI so later changes expose renewed disagreement.

From my technical-communication perspective, the important AI-documentation distinction is reviewability, not fluency. Structured source fields let a reviewer inspect a contract claim individually. Generated prose can sound precise while concealing whether “supported” describes syntax, validation, or application behavior. Keep a compact reference table for consumers seeking an acceptance answer; add explanatory prose when consequences matter. A longer paragraph that still merges distinct states is not an acceptable replacement.

ConditionDecision rule
If choosing the sole request-field contractChoose the schema-backed state table with linked executable fixtures; reject a prose-only “nullable” label.
If a promised behavior lacks its own rowExpand the state table before publication; link that behavior to a fixture that checks the promise.
If any artifact disagrees about acceptanceBlock publication as internally inconsistent; the release threshold is zero contradictions.
If application meaning affects consumer behaviorChoose the compact table plus explanatory prose, not prose that collapses omission and null.
If only a single successful request is availablePublish it as a supplement, not the contract; it establishes only the illustrated request.
Choose the Documentation Pattern — Null vs Missing Request Fields

What the Data Doesn't Tell You

Schema-valid null is not an instruction to clear data. A request can satisfy its declared value constraints while leaving the server's intended operation unspecified: explicit null might clear a stored value, record an unknown value, or trigger rejection under a business rule. Documentation must identify the endpoint's actual interpretation, including any conditions that change it. Inferring that interpretation from null's membership in a type union confuses admissible input with application behavior. The contract rule remains necessary; it is not a complete account of what the endpoint does.

Composition introduces a separate logical limit. Consider the constructed schema fragment oneOf: [{"type":"number"},{"type":"integer"}]. The value 1 matches both branches, so oneOf rejects it: acceptance requires exactly one matching branch. By contrast, {"type":["number","integer"]} accepts that value because membership in either listed type suffices. This is a logical counterexample to “oneOf is always interchangeable with a type array,” not a measured tooling defect. Disjoint branches can produce equivalent acceptance behavior, but that equivalence cannot be generalized to overlapping branches. The relevant question is whether branches overlap, not whether their rendered descriptions look similar.

Serialization can erase the distinction before validation ever begins. Suppose a caller supplies {"displayName":null}, but the SDK's serializer is configured to omit null-valued members. The transmitted object may be {}, even though the caller explicitly supplied null in memory. A server then receives omission, not evidence of the caller's intent. Evaluating a particular SDK therefore requires inspecting the serialized request body under its actual serializer configuration. Record the input object and the transmitted body separately; an object debugger or generated method signature cannot establish what crossed the network.

Tool compatibility is another independent uncertainty. Validators, documentation renderers, and code generators can advertise the same specification family while differing in the constructs they validate, display accurately, or preserve in generated clients. A compatibility conclusion must name the tested tool version and configuration, and specify the behavior exercised. Successful schema parsing establishes only that the document was accepted at that stage. It does not establish correct instance validation, an unambiguous rendered explanation, or a generated client's ability to transmit explicit null. Nor does legacy nullable: true make a property optional and null-accepting in OpenAPI 3.1.

From a technical communication perspective, correctness and comprehension are different evidence claims. Normative specifications define conformance; they do not quantify whether a particular explanation helps readers distinguish omission from null, or whether AI-generated documentation increases error rates. A structured-authoring and AI-documentation research lens motivates asking those questions, not answering them by assertion. Any evaluation would need to distinguish readers' interpretation errors from serializer-induced payload changes and implementation behavior. Without that separation, an observed failure could be assigned to the wrong cause. Before declaring an explanation or toolchain successful, identify which claim was actually checked: endpoint meaning, serialized payload, implemented schema behavior, or reader understanding.

What the Data Doesn't Tell You — Null vs Missing Request Fields

Work 3 JSON Merge Patch Cases

The JSON Merge Patch specification’s deletion fixture makes the distinction observable: a valid patch can contain null while its resulting document contains no null-valued member. The JSON Merge Patch specification’s Appendix A provides worked examples. The selected fixtures below demonstrate omission, explicit null, and string replacement. Their operational meaning comes from application/merge-patch+json, not from the request schema’s type declarations.

For an endpoint whose resource has string-valued members a and b, use this complete illustrative request schema under the application/merge-patch+json request content entry:

{"type":"object","properties":{"a":{"type":["string","null"]},"b":{"type":["string","null"]}},"additionalProperties":false}

This is a constrained endpoint contract, not a schema for every possible merge-patch document. It accepts object patches containing only the named properties, with string or null values. Neither property appears in an enclosing required array; that array is absent, so neither must be supplied. The type unions independently admit explicit null. Substituting nullable: true would not establish either optional presence or null acceptance in OpenAPI 3.1.

The following before/patch/after fixtures reproduce the literal values from the JSON Merge Patch specification, Appendix A. Read the patch column as the request body, not as a partial rendering of the desired stored document.

BeforePatchAfter
{"a":"b"}{"b":"c"}{"a":"b","b":"c"}
{"a":"b","b":"c"}{"a":null}{"b":"c"}
{"a":"b"}{"a":"c"}{"a":"c"}

Document property a as follows: “Omit a to preserve its existing value. Supply a as null to remove the member. Supply a as a string to replace its existing value with that string.” These statements describe this endpoint’s merge-patch behavior. In the omission fixture, changing b leaves a untouched; in the deletion fixture, b survives while a disappears; in the replacement fixture, a remains present with its new string.

The null allowance belongs to the patch input’s instruction vocabulary. Under JSON Merge Patch semantics, null requests removal rather than assignment of a stored null value. Consequently, the request schema is not evidence that the resulting resource representation permits null. The deletion fixture’s expected result distinguishes those claims directly: a is absent, not present with a null value.

Turn each table row into a test with separate request-validation and resulting-document assertions. First require the patch to validate against the declared request schema. Then apply it to the exact before document and require structural JSON equality with the after document. For deletion, explicitly assert that a is absent; a lookup that treats missing and null identically cannot establish the documented behavior.

The three selected fixtures demonstrate example coverage only, not semantic completeness. Nested structures, arrays, and non-object patches remain outside the demonstrated coverage. Keep that boundary attached to the tests so passing them cannot be mistaken for unrestricted JSON Merge Patch conformance.

Work 3 JSON Merge Patch Cases — Null vs Missing Request Fields

How to Choose Well

A nullable-syntax migration is not a search-and-replace operation. According to OpenAPI Nullable vs Optional Contract Tests, composition and generator behavior must be checked before mechanically replacing nullable syntax; the desired outcome is an identical acceptance matrix. Check the composed schema, not merely the edited property declaration, and verify what generated clients actually transmit. A cleaner-looking declaration is not a successful migration if previously accepted omission or null is silently rejected—or previously rejected input becomes accepted.

The same source’s supplied excerpt begins an exception concerning migration intent but truncates before explaining it. That fragment cannot justify a particular change in accepted requests. Keep syntax migration and intentional contract changes separately reviewable. In OpenAPI 3.1, nullable: true does not make a property optional and is not the mechanism for permitting null. Mandatory presence belongs in the enclosing object’s required array; explicit null belongs in the property’s type union only when permitted.

For a concrete authoring check, consider an illustrative create request with a projectName field. If creation requires a usable client-supplied name, admitting null does not solve the missing-input problem; it authorizes an unusable value. Excluding null alone also does not establish usability: applicable value constraints still matter. If the server can generate a name instead, document the condition that selects that alternative rather than leaving readers to infer it from optionality or a default annotation.

Apply the following decision branches before approving the contract, client recommendation, or documentation rewrite.

If the published artifact declares OpenAPI 3.0.x, choose a versioned migration before introducing 3.1 schema syntax; preserve request acceptance unless a contract change is separately intended and reviewed. If it declares 3.1.x, reject new templates that use nullable to allow null. Choose type-union authoring, with composition and generator checks as migration gates.

If a create operation cannot proceed without a usable client-supplied value, choose mandatory, non-null input: include the property in the enclosing object’s required array and exclude "null" from its type union. If server generation is available, specify its triggering condition separately; do not substitute a null placeholder for that condition.

If an optional setting falls back when omitted, choose documentation that states whether the server actually applies the fallback and whether explicit null is accepted. Keep those claims separate. If the only evidence is a schema default annotation, do not claim automatic population of request data; obtain confirmation of endpoint behavior.

If an SDK collapses “not supplied” and “supplied as null,” choose a presence-aware wrapper or an explicitly tested serialization path before recommending it. Check the outgoing request body, not just the in-memory representation: the omission path must leave the member absent, while the explicit-null path must emit it with a null value.

If an AI rewrite changes “may be omitted” to “may be null,” choose contract-owner review before publication. Accept the rewrite only after checking the changed claim against both the authoritative schema and endpoint behavior. If they disagree, hold publication for resolution rather than letting fluent wording decide which contract readers receive.

What to do next

StepActionWhy it matters
1For name and displayName, record separately whether omission is permitted and whether explicit null is permitted.Presence and accepted values are independent contract decisions.
2Add displayName to the enclosing object’s required array only if it must be supplied.As w3tutorials.net explains, required controls presence; leaving a property out permits omission.
3For a string-valued displayName, use type: ["string", "null"] only when explicit null is allowed; otherwise use type: "string".A required property can still accept null. Its value schema determines that permission.
4Test {}, {"name":null}, and {"name":"Ada"} against the declared contract; distinguish m

Frequently Asked Questions

If displayName is in the enclosing object's required array, can it still be null?

Yes—requiring a property does not, by itself, prohibit null, and a mandatory property can accept null without accepting omission.

What is the difference between sending {} and {"name":null}?

The bodies {} and {"name":null} communicate different things: the former omits name; the latter supplies it with an explicit null value.

Does nullable: true in OpenAPI 3.1 make a property optional and null-capable?

No, setting nullable: true does not make a property optional and null-capable in OpenAPI 3.1; use the enclosing required array for presence and a type union containing "null" for null acceptance.

Where does JSON Schema's required keyword belong?

JSON Schema's required keyword takes an array of property names and constrains an object instance; it is not a Boolean flag attached to the property being required.

Does requestBody.required require every member inside the HTTP request body?

No, requestBody.required determines whether the HTTP request body itself must be supplied, and it does not require every member inside that body.

What are the seven permitted type-name strings in JSON Schema Validation Section 6.1.1?

The seven permitted type-name strings are null, boolean, object, array, number, string, and integer.

Quick answers

How does the codegenes.net validation guide distinguish between missing-field failures and null-value failures?It distinguishes failure caused by omitting a required field from a 'Field may not be null' error caused by submitting a prohibited null value.
What is the difference in meaning between the request bodies {} and {"name":null}?The former omits the name property, while the latter supplies it with an explicit null value.
How does the OpenAPI 3.1.0 specification define the mechanism for requiring property presence versus accepting null values?It uses the enclosing object's required array for presence and a type union containing "null" for null acceptance.
What does the OpenAPI Request Body Object's required property determine?It determines whether the HTTP request body itself must be supplied, not whether every member inside that body is required.
According to the JSON specification, is 'missing' considered a JSON value?No, missing is neither another JSON value nor a token clients can transmit.

Also worth reading: OpenAPI 4.0's nullable: A Parse Failure Disguised as Spec Upgrade: OpenAPI 4.0's nullable: A Parse · OpenAPI 3: One Nullable Keyword Deleted, Three Encodings Win: OpenAPI 3: One Nullable Keyword · Double Trouble: Navigating the Pitfalls and Payoffs of Having a Co-Founder: Double Trouble: Navigating the Pitfalls

Research Methodology & Editorial Standards

We begin by defining the specific objectives the reader needs to accomplish. Primary product documentation and authoritative secondary sources are assembled into a verified research corpus; drafting occurs only after this foundation is in place.

Every quantitative claim is subjected to dual-source verification. Any figure that cannot be independently corroborated is either qualified or omitted.

Published · Last reviewed · Owned by the Specswriter editorial desk (About, Contact, Privacy).