Skip to content

Weird error message when z.coerce.date() fails to coerceย #5408

@AlonMiz

Description

@AlonMiz

Summary

When using z.coerce.date() with a value that cannot be coerced into a valid Date, the error message is misleading:

z.coerce.date().parse('www');
// => ZodError: Invalid input: expected date, received Date

This reads as if a Date was provided, when in fact a string was provided and the coercion produced an invalid Date. It would be helpful if the error communicated that coercion failed and/or showed the original input type/value.


Repro

import { z } from 'zod';

const schema = z.coerce.date();

schema.parse('www');          // Invalid input: expected date, received Date
schema.parse('not-a-date');   // same
schema.parse('2025-13-99');   // same (invalid calendar date)

(Using Zod v4 โ€” reproducible in a fresh project.)


Actual behavior

  • Error message: Invalid input: expected date, received Date
  • This suggests the input was a Date, which is incorrect. The input was a string and the coercion produced new Date("www") โ†’ Invalid Date.

Expected behavior

A clearer message, for example (any of these would be great):

  • Invalid date: could not coerce value "www" into a valid Date
  • Invalid input: expected a date, received string "www" (coercion failed)
  • Invalid input: expected valid Date after coercion, got Invalid Date (from "www")

Key points:

  • Indicate original input type/value (string "www").
  • Indicate that coercion happened and failed because the result is an Invalid Date.

Why this matters

  • The current message can send users on a wild goose chase, thinking theyโ€™re passing a Date incorrectly.
  • Clearer messaging speeds up debugging, especially in schemas with nested objects where the path matters.

Possible directions (implementation ideas)

  • In the coerce.date() pipeline, after coercion (new Date(value)), detect Number.isNaN(date.getTime()):

    • If Invalid Date, raise a custom issue code (e.g., "invalid_date") that includes:

      • the original input type and a safe preview of the value,
      • a hint that coercion failed.
  • Alternatively, adjust the error constructor for ZodDate to include a special branch when the input is already a Date but invalid vs. when the input was coerced from a non-Date type and resulted in Invalid Date.

  • (Nice-to-have) Add a short value preview with truncation and JSON-stringify to avoid giant messages.


Environment

  • Zod: v4.x
  • Node: v18+/v20 (reproducible)
  • TS: 5.x

Minimal code sandbox

import { z } from 'zod';
z.coerce.date().parse('www');

Thanks for the awesome library! ๐Ÿ™Œ

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions