{"record":{"id":"c4bd04a73b772b17","repo":"can1357/oh-my-pi","slug":"number-min-must-not-be-nan","errorCode":null,"errorMessage":"number min must not be NaN","messagePattern":"number min must not be NaN","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/zod.ts","lineNumber":139,"sourceCode":"\t\t\tconst result = schema(value);\n\t\t\tif (!(result instanceof type.errors)) return { success: true, data: result };\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tmessage: result.summary,\n\t\t\t\t\tissues: result.map(issue => ({ path: [...issue.path], message: issue.problem })),\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tmin(bound: number): ZodLikeSchema<Out> {\n\t\t\tconst ir = schema.ir;\n\t\t\tif (ir.k === \"string\" || ir.k === \"array\") {\n\t\t\t\tlengthBound(\"min\", schema, bound);\n\t\t\t\tconst min = ir.min === undefined ? bound : Math.max(ir.min, bound);\n\t\t\t\treturn next(restrictBase(schema, { ...ir, min }));\n\t\t\t}\n\t\t\tif (ir.k === \"number\") {\n\t\t\t\tif (Number.isNaN(bound)) throw new OmpTypeError(\"number min must not be NaN\");\n\t\t\t\tif (ir.min !== undefined && ir.min >= bound) return next(restrictBase(schema, ir));\n\t\t\t\treturn next(restrictBase(schema, { ...ir, min: bound, xmin: false }));\n\t\t\t}\n\t\t\tthrow new OmpTypeError(`cannot apply min to ${ir.k}`);\n\t\t},\n\t\tmax(bound: number): ZodLikeSchema<Out> {\n\t\t\tconst ir = schema.ir;\n\t\t\tif (ir.k === \"string\" || ir.k === \"array\") {\n\t\t\t\tlengthBound(\"max\", schema, bound);\n\t\t\t\tconst max = ir.max === undefined ? bound : Math.min(ir.max, bound);\n\t\t\t\treturn next(restrictBase(schema, { ...ir, max }));\n\t\t\t}\n\t\t\tif (ir.k === \"number\") {\n\t\t\t\tif (Number.isNaN(bound)) throw new OmpTypeError(\"number max must not be NaN\");\n\t\t\t\tif (ir.max !== undefined && ir.max <= bound) return next(restrictBase(schema, ir));\n\t\t\t\treturn next(restrictBase(schema, { ...ir, max: bound, xmax: false }));\n\t\t\t}\n\t\t\tthrow new OmpTypeError(`cannot apply max to ${ir.k}`);","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/zod.ts#L121-L157","documentation":"In the zod-compat layer, `.min()` applied to a number schema rejects NaN bounds with `number min must not be NaN` (the length-bound safe-integer rule does not apply to numbers, but NaN is still meaningless as a minimum). It is thrown at builder time, before any value is validated.","triggerScenarios":"`z.number().min(Number.NaN)` or `z.number().min(someVar)` where `someVar` is NaN — commonly `Number(undefined)`, a failed `parseFloat` of config, or `0/0` in a computed default.","commonSituations":"Deriving minimum limits from env/config that is unset or unparsable; spreading optional option objects where the min field was computed earlier and became NaN.","solutions":["Validate the bound before calling: `if (!Number.isNaN(min)) schema.min(min)`.","Fix the upstream computation that yields NaN (default the config value, guard division).","Omit the `.min()` call when no numeric lower bound is intended."],"exampleFix":"// before\nnum.min(Number(opts.minimum)); // NaN when opts.minimum undefined\n// after\nconst m = Number(opts.minimum);\nif (Number.isFinite(m)) num.min(m);","handlingStrategy":"validation","validationCode":"function finiteMin(n: number | undefined): number | undefined {\n  if (n === undefined) return undefined;\n  if (Number.isNaN(n)) throw new RangeError('number min must not be NaN');\n  return n;\n}\n// use: num.min(finiteMin(rawMin)!)","typeGuard":"function isNumericMin(v: unknown): v is number {\n  return typeof v === \"number\" && !Number.isNaN(v);\n}","tryCatchPattern":"try {\n  const s = z.number().min(rawMin);\n} catch (err) {\n  if (err instanceof Error && err.message === 'number min must not be NaN') {\n    throw new Error(`Minimum limit config value is not a number`);\n  }\n  throw err;\n}","preventionTips":["Guard Number()/parseFloat results with Number.isNaN before using as bounds.","Default unset config values instead of letting undefined become NaN through Number().","Omit .min() when the bound cannot be determined."],"tags":["omptype","zod-compat","number-bound","invalid-argument"],"backgroundTag":"non-finite-number-option","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}