{"record":{"id":"700e3601693045b6","repo":"denoland/deno","slug":"invalid-name-must-not-be-infinity-or-nan","errorCode":null,"errorMessage":"invalid ${name}, must not be infinity or NaN","messagePattern":"invalid (.+?), must not be infinity or NaN","errorType":"validation","errorClass":"Deno.errors.InvalidData","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_fs/_fs_lutimes.ts","lineNumber":37,"sourceCode":"  PromisePrototypeThen,\n} = primordials;\n\ntype TimeLike = number | string | Date;\ntype PathLike = string | Buffer | URL;\n\nfunction getValidUnixTime(\n  value: TimeLike,\n  name: string,\n): [number, number] {\n  if (typeof value === \"string\") {\n    value = Number(value);\n  }\n\n  if (\n    typeof value === \"number\" &&\n    (NumberIsNaN(value) || !NumberIsFinite(value))\n  ) {\n    throw new Deno.errors.InvalidData(\n      `invalid ${name}, must not be infinity or NaN`,\n    );\n  }\n\n  const unixSeconds = toUnixTimestamp(value);\n\n  const seconds = MathTrunc(unixSeconds);\n  const nanoseconds = MathTrunc((unixSeconds * 1e3) - (seconds * 1e3)) * 1e6;\n\n  return [\n    seconds,\n    nanoseconds,\n  ];\n}\n\nexport function lutimes(\n  path: PathLike,\n  atime: TimeLike,","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_fs/_fs_lutimes.ts#L19-L55","documentation":"getValidUnixTime (ext/node/polyfills/_fs/_fs_lutimes.ts) converts each atime/mtime of fs.lutimes/fs.lutimesSync to [seconds, nanoseconds]. Strings are coerced with Number(value); if the result is NaN or Infinity, it throws Deno.errors.InvalidData with 'invalid ${name}, must not be infinity or NaN' where name is 'atime' or 'mtime'. lutimes changes timestamps of a symlink itself, so both time arguments must be finite.","triggerScenarios":"fs.lutimes(link, 'not-a-date', new Date(), cb) (Number('not-a-date') is NaN); fs.lutimes(link, Infinity, 0, cb); passing an empty string or unparsable numeric string as atime/mtime.","commonSituations":"Reading timestamps from config or CLI args that may be empty/unparsable; computing mtime as a division that yields Infinity (e.g., 1/0); passing Date objects serialized as strings that are not numeric.","solutions":["Pass Date objects or numeric seconds/ms directly instead of strings","Sanitize inputs: coerce and check Number.isFinite before calling lutimes","If the value comes from user input, reject it early with your own validation message"],"exampleFix":"// before\nawait fs.promises.lutimes(link, cfg.atime, Date.now()); // cfg.atime = '' -> NaN\n\n// after\nconst at = Number(cfg.atime);\nif (!Number.isFinite(at)) throw new TypeError('cfg.atime must be a finite number');\nawait fs.promises.lutimes(link, at, Date.now());","handlingStrategy":"validation","validationCode":"const toFiniteUnix = (v) => {\n  const n = typeof v === 'string' ? Number(v) : v;\n  if (typeof n !== 'number' || !Number.isFinite(n)) {\n    throw new TypeError(`time must be finite, got ${String(v)}`);\n  }\n  return n;\n};","typeGuard":"function isValidTimeLike(v) {\n  if (typeof v === 'string') return Number.isFinite(Number(v));\n  return typeof v === 'number' || v instanceof Date;\n}","tryCatchPattern":"try { await fsp.lutimes(p, at, mt); } catch (e) { if (e instanceof Deno.errors.InvalidData) { /* fix time source */ } else throw e; }","preventionTips":["Pass Date objects instead of string timestamps","Validate config-sourced numbers with Number.isFinite before use","Remember strings are coerced with Number(), not Date.parse — '2024-01-01' is not valid here"],"tags":["node-compat","fs","lutimes","timestamps","validation"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}