Skip to content

Dart: null-guard nullable date fields in toJson#2879

Merged
schani merged 2 commits into
masterfrom
fix/dart-nullable-date-tojson
Jul 6, 2026
Merged

Dart: null-guard nullable date fields in toJson#2879
schani merged 2 commits into
masterfrom
fix/dart-nullable-date-tojson

Conversation

@schani

@schani schani commented Jul 6, 2026

Copy link
Copy Markdown
Member

Problem

Generated Dart code for a nullable date field (a yyyy-mm-dd string that is sometimes null) crashes at runtime when serializing an instance whose date is null:

Unhandled exception: Null check operator used on a null value

The generated toJson looked like this:

"dueDate": "${dueDate!.year.toString().padLeft(4, '0')}-${dueDate!.month.toString().padLeft(2, '0')}-${dueDate!.day.toString().padLeft(2, '0')}",
"createdAt": createdAt?.toIso8601String(),

Nullable date-time fields were handled correctly (?.toIso8601String()); only the "date" transformed-string kind used the null-assertion operator with no guard. This happens with default options, compiles fine, and only fails at runtime.

Root cause

In packages/quicktype-core/src/language/Dart/DartRenderer.ts, toDynamicExpression's "date" case has a dedicated branch for null-safe nullable dates, but that branch emitted the same unguarded template string as the non-nullable case, just with ! inserted before .year/.month/.day.

Fix

Prefix the template string with a null guard in the nullable null-safe branch, mirroring the == null ? null : convention already used by the generated fromJson:

"dueDate": dueDate == null ? null : "${dueDate!.year.toString().padLeft(4, '0')}-${dueDate!.month.toString().padLeft(2, '0')}-${dueDate!.day.toString().padLeft(2, '0')}",

The non-null-safe (--null-safety false) and --required-props code paths are unchanged.

Tests

The regression test was added first and demonstrated failing before the fix. New fixture input test/inputs/json/priority/bug2590.json — an object with a small array whose elements have a nullable date ("2023-01-15" / null) and a nullable date-time. Generating Dart from it on unfixed master produced the unguarded

"dueDate": "${dueDate!.year.toString().padLeft(4, '0')}-..."

which throws Null check operator used on a null value when the dart fixture's parser.dart round-trips the second array element ("dueDate": null) through topLevelToJson. After the fix the generated line is null-guarded and the round trip yields null for that field.

Verification

  • Rebuilt and confirmed generated Dart output pre-fix (unguarded !.year) vs post-fix (dueDate == null ? null : "..."); nullable date-time (?.toIso8601String()) and non-nullable paths unchanged.
  • Ran the new input through locally runnable fixtures: FIXTURE=typescript,javascript,golang,rust script/test test/inputs/json/priority/bug2590.json — all pass, so the new priority input doesn't destabilize those languages.
  • Manually round-tripped the generated Python for the new input (the python fixture needs mypy, which isn't installed here) — output matches modulo date formatting that the test harness's moment-based comparison accepts.
  • Not verified locally: actually executing the generated Dart (dart is not installed here), and CI-only languages (C#, Java, Kotlin, PHP, Swift, Elm, …) against the new priority input — CI will exercise those.

Fixes #2590

🤖 Generated with Claude Code

For a nullable "date" transformed-string field, the Dart renderer's
toJson emitted a template string over `x!.year` / `x!.month` / `x!.day`
with no null check, so serializing an instance whose date field is null
threw "Null check operator used on a null value" at runtime.  Nullable
date-time fields were already handled correctly with
`?.toIso8601String()`.

Emit `x == null ? null : "${x!...}"` in the null-safe nullable branch,
mirroring the null guards used in fromJson.

Adds test/inputs/json/priority/bug2590.json, a fixture input with a
nullable yyyy-mm-dd date field, so the dart fixture round-trips it in
CI.

Fixes #2590

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@schani schani merged commit 8e59fa7 into master Jul 6, 2026
22 checks passed
@schani schani deleted the fix/dart-nullable-date-tojson branch July 6, 2026 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Null check error in Generated toJson methods in dart having nullable DateTime values

1 participant