denoland/deno · error · Deno.errors.InvalidData

invalid ${name}, must not be infinity or NaN

Error message

invalid ${name}, must not be infinity or NaN

What it means

futimes and futimesSync normalize atime/mtime through _getValidTime: strings are converted with Number(), and if the resulting number is NaN or non-finite the function throws Deno.errors.InvalidData. This guards the OS-level utimensat call against timestamps it cannot represent.

Source

Thrown at ext/node/polyfills/fs.ts:1500

    throw new ERR_INVALID_ARG_TYPE("fd", "number", fd);
  }
  validateInteger(len, "len");
  op_node_fs_ftruncate_sync(fd, MathMax(0, len));
}

function _getValidTime(
  time: number | string | Date,
  name: string,
): number | Date {
  if (typeof time === "string") {
    time = Number(time);
  }

  if (
    typeof time === "number" &&
    (NumberIsNaN(time) || !NumberIsFinite(time))
  ) {
    throw new Deno.errors.InvalidData(
      `invalid ${name}, must not be infinity or NaN`,
    );
  }

  return toUnixTimestamp(time);
}

function futimes(
  fd: number,
  atime: number | string | Date,
  mtime: number | string | Date,
  callback: CallbackWithError,
) {
  if (!callback) {
    throw new Deno.errors.InvalidData("No callback function supplied");
  }
  if (typeof fd !== "number") {
    throw new ERR_INVALID_ARG_TYPE("fd", "number", fd);

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Pass Date objects or finite numbers (epoch seconds) instead of free-form strings
  2. Validate with Number.isFinite(Number(v)) before the call when input is external
  3. Default missing timestamps to a known value such as Date.now() / 1000

Example fix

// before
fs.futimes(fd, ts, mtime, cb); // ts = 'abc' from argv -> NaN

// after
const t = Number(ts);
fs.futimes(fd, Number.isFinite(t) ? t : Date.now() / 1000, mtime, cb);
Defensive patterns

Strategy: validation

Validate before calling

const toTime = (v: number | string | Date): number => {
  const n = typeof v === 'string' ? Number(v) : (v as number);
  if (!Number.isFinite(n)) throw new RangeError('invalid time');
  return n;
};
toTime(atime); toTime(mtime); // before fs.futimes

Type guard

const isValidTime = (v: unknown): v is number | Date =>
  typeof v === 'number' ? Number.isFinite(v)
    : typeof v === 'string' ? Number.isFinite(Number(v))
    : v instanceof Date && !isNaN(v.getTime());

Try / catch

try {
  await fs.promises.futimes(fd, atime, mtime);
} catch (err) {
  if (err instanceof Deno.errors.InvalidData) { /* bad timestamp input: fix source */ }
  throw err;
}

Prevention

When it happens

Trigger: fs.futimes(fd, 'not-a-date', new Date(), cb) (Number('not-a-date') is NaN); passing Infinity or NaN directly; a numeric string like 'abc' sourced from config or CLI flags.

Common situations: Touch-like scripts taking timestamps from user input; empty-string defaults that become NaN; values parsed from headers or query strings without validation.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/928b211e33124cc2. Report an issue: GitHub.