napi-rs/napi-rs · error · DateExpected

Found invalid date

Error message

Found invalid date

What it means

Thrown when converting a JS Date to `DateTime<Local>`: `napi_get_date_value` returns milliseconds since epoch, and `Local.timestamp_millis_opt` fails to produce a unique/valid local datetime (LocalResult::None or Ambiguous). The library raises Status::DateExpected with this message instead of returning a DateTime.

Solutions

  1. Validate the Date on the JS side before calling: check `!Number.isNaN(date.getTime())`.
  2. Verify the epoch milliseconds do not fall into a DST gap for the machine's local timezone, or use a UTC-based type (`DateTime<Utc>` vs `NaiveDateTime`) on the Rust side.
  3. Set the process/container TZ to a known zone (e.g. TZ=UTC) if DST ambiguity is the cause.
  4. Inspect the incoming Date with `date.toISOString()` in JS to confirm it represents a real instant.

Example fix

// before
fn schedule(dt: DateTime<Local>) { ... }
schedule(new Date(undefined));
// after (JS side guard)
const d = new Date(input);
if (Number.isNaN(d.getTime())) throw new Error('invalid date');
schedule(d);
Defensive patterns

Strategy: validation

Validate before calling

function assertValidDate(d) {
  if (!(d instanceof Date) || Number.isNaN(d.getTime())) {
    throw new TypeError('Expected a valid Date, got: ' + String(d));
  }
}

Type guard

function isValidDate(v) { return v instanceof Date && !Number.isNaN(v.getTime()); }

Try / catch

try { mod.schedule(d); } catch (e) { if (String(e.message).includes('Found invalid date')) { console.error('Date invalid or falls in DST gap'); } else throw e; }

Prevention

When it happens

Trigger: Calling a #[napi] function with a `DateTime<Local>` (or `DateTime<Utc>` mapped through this impl) parameter when the epoch milliseconds map to a nonexistent or ambiguous local time, or the JS value is an invalid Date (NaN time, e.g. `new Date(NaN)`).

Common situations: DST transitions where `new Date(...)` epoch value maps into a skipped/ambiguous local hour in the user's timezone; passing `new Date(undefined)` or `Invalid Date` from JS.

Related errors


AI-assisted analysis of napi-rs/napi-rs@39bd1205e4 (2026-09-13). Data as JSON: /api/errors/1be4717fd5be21e9. Report an issue: GitHub.

Appendix: source

Thrown at crates/napi/src/bindgen_runtime/js_values/date.rs:148

    Ok(ptr)
  }
}

impl<Tz: TimeZone> FromNapiValue for DateTime<Tz>
where
  DateTime<Tz>: From<DateTime<Local>>,
{
  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
    let mut milliseconds_since_epoch_utc = 0.0;

    check_status!(
      unsafe { sys::napi_get_date_value(env, napi_val, &mut milliseconds_since_epoch_utc) },
      "Failed to convert napi value into rust type `DateTime`",
    )?;

    match Local.timestamp_millis_opt(milliseconds_since_epoch_utc as i64) {
      LocalResult::Single(dt) => Ok(dt.into()),
      _ => Err(Error::new(
        Status::DateExpected,
        "Found invalid date".to_owned(),
      )),
    }
  }
}

View on GitHub (pinned to 39bd1205e4)