{"record":{"id":"139b1f9e315e24db","repo":"agalwood/Motrix","slug":"label-must-be-a-positive-safe-integer-timestamp","errorCode":null,"errorMessage":"${label} must be a positive safe integer timestamp","messagePattern":"(.+?) must be a positive safe integer timestamp","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"src/core/lib/sqlite-integers.ts","lineNumber":47,"sourceCode":"  const converted = safeIntegerFromSql(value, label)\n  if (converted < 0) {\n    throw new RangeError(`${label} must be non-negative`)\n  }\n  return converted\n}\n\nexport function requireSafeTimestamp(value: number, label: string): void {\n  if (!Number.isSafeInteger(value)) {\n    throw new RangeError(`${label} must be a safe integer timestamp`)\n  }\n}\n\nexport function requireSafePositiveTimestamp(\n  value: number,\n  label: string\n): void {\n  if (!Number.isSafeInteger(value) || value <= 0) {\n    throw new RangeError(`${label} must be a positive safe integer timestamp`)\n  }\n}\n","sourceCodeStart":29,"sourceCodeEnd":50,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/lib/sqlite-integers.ts#L29-L50","documentation":"Thrown by requireSafePositiveTimestamp when the value is not a safe integer OR is <= 0. Stricter than requireSafeTimestamp: it enforces that a timestamp denotes a real forward-pointing instant (used for expiry, created-at, scheduled times).","triggerScenarios":"Calling requireSafePositiveTimestamp(value, label) with 0, a negative number, NaN, or a fractional value. Typical when an optional timestamp defaulted to 0, or a Date is in the past represented as a negative delta.","commonSituations":"Defaulting an 'expiry' or 'notBefore' field to 0 meaning 'unset'; subtracting two timestamps and passing the result; receiving 0 from a missing JSON field; clock-skew corrections that produce non-positive values.","solutions":["Distinguish 'unset' from 'set' at the type level (use undefined/null) instead of sentinel 0.","Validate the upstream payload has the field before calling the guard.","If 0 is a legitimate sentinel in your schema, branch around it rather than passing it to the positive guard.","For computed deltas, clamp or branch on the sign before validation."],"exampleFix":"// before\nrequireSafePositiveTimestamp(expiry ?? 0, 'expiry')\n// after\nif (expiry === undefined) throw new TypeError('expiry required')\nrequireSafePositiveTimestamp(expiry, 'expiry')","handlingStrategy":"validation","validationCode":"function isPositiveSafeTimestamp(value: unknown): value is number {\n  return typeof value === 'number' && Number.isSafeInteger(value) && value > 0\n}\nif (input.expiry === undefined || !isPositiveSafeTimestamp(input.expiry)) {\n  throw new TypeError('expiry must be a positive safe integer')\n}\nrequireSafePositiveTimestamp(input.expiry, 'expiry')","typeGuard":"function isPositiveSafeTimestamp(value: unknown): value is number {\n  return typeof value === 'number' && Number.isSafeInteger(value) && value > 0\n}","tryCatchPattern":"try {\n  requireSafePositiveTimestamp(expiry, 'expiry')\n} catch (e) {\n  if (e instanceof RangeError) {\n    // treat as 'no expiry set' or reject the payload\n  } else throw e\n}","preventionTips":["Represent 'unset' with undefined/null at the type level instead of sentinel 0.","Validate payload presence before calling the positive guard.","For computed deltas, branch on the sign rather than passing through."],"tags":["timestamp","validation","type-coercion"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}