Skip to content

[typescript-fetch] guard required date properties against null - #24509

Open
mvhenten wants to merge 1 commit into
OpenAPITools:masterfrom
mvhenten:fix/typescript-fetch-required-date-null-guard
Open

[typescript-fetch] guard required date properties against null#24509
mvhenten wants to merge 1 commit into
OpenAPITools:masterfrom
mvhenten:fix/typescript-fetch-required-date-null-guard

Conversation

@mvhenten

@mvhenten mvhenten commented Jul 28, 2026

Copy link
Copy Markdown

A server returns null for a property the schema marks required with format: date. The generated client turns it into 1970-01-01T00:00:00.000Z, a valid Date that flows into business logic unnoticed. An absent value becomes Invalid Date, and serializing that same payload back throws RangeError: Invalid time value.

#24215 added guards for the optional and nullable date cases. Required non-nullable dates were left unguarded; this completes that work.

Required date and date-time are the only property kinds in modelGeneric.mustache that fabricate a value from null. Every other required property passes the raw value through ('x': json['x'], 'x': XFromJSON(json['x'])). Dates now do the same: null stays null, absent stays absent. Passing the value through instead of forcing undefined also keeps the output compiling under strictNullChecks, since json is any and no cast is needed.

A required date arriving as null does violate the schema. The failure mode for that should not be a plausible-looking wrong date.

Generated code

 export function FormatTestFromJSONTyped(json: any, ignoreDiscriminator: boolean): FormatTest {
-        'date': (new Date(json['date'])),
+        'date': (json['date'] == null ? json['date'] : new Date(json['date'])),
 export function FormatTestToJSONTyped(value?: FormatTest | null, ignoreDiscriminator: boolean = false): any {
-        'date': value['date'].toISOString().substring(0,10),
+        'date': value['date'] == null ? value['date'] : value['date'].toISOString().substring(0,10),

Executed behaviour

Client generated from a spec with a required date and a required date-time, run through FromJSON and back through ToJSON:

server response before after
{"requiredDate": null} 1970-01-01T00:00:00.000Z"1970-01-01" nullnull
{} Invalid Date → throws RangeError: Invalid time value undefinedundefined
{"requiredDate": "2024-03-05"} 2024-03-05T00:00:00.000Z"2024-03-05" unchanged

Optional, nullable and required-nullable dates are unaffected, and both variants typecheck under --strict.

Sample output changes are limited to those four lines in FormatTest (default-v3.0, kebab-case, snakecase-discriminator). No other typescript-fetch sample output changed. TypeScriptFetchClientCodegenTest.testRequiredDatesAreNullGuarded covers the required date-time case, which no existing sample spec exercises.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/typescript-fetch*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@leonyu


Summary by cubic

Fix null handling for required date and date-time fields in typescript-fetch so null or missing values pass through unchanged, avoiding fabricated dates and runtime errors.

  • Bug Fixes
    • Added null guards for required date/date-time in modelGeneric.mustache for both FromJSON and ToJSON.
    • null stays null, absent stays undefined; prevents 1970-01-01T00:00:00.000Z and RangeError: Invalid time value.
    • Added test testRequiredDatesAreNullGuarded and required-date.yaml; updated FormatTest samples only.

Written for commit 28165e9. Summary will update on new commits.

Review in cubic

A required date or date-time property was deserialized with an unguarded
new Date(json[...]), turning a null value into 1970-01-01 and an absent
value into Invalid Date, which then throws RangeError on serialization.

Pass a nullish value through unchanged in both directions, as the
template already does for every other required property type.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

Re-trigger cubic

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.

1 participant