{"record":{"id":"6278dd3fab650adc","repo":"quasarframework/quasar","slug":"invalid-jalaali-year-jy","errorCode":null,"errorMessage":"Invalid Jalaali year ${jy}","messagePattern":"Invalid Jalaali year (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/src/utils/date/private.persian.js","lineNumber":64,"sourceCode":"\n/*\n    This function determines if the Jalaali (Persian) year is\n    leap (366-day long) or is the common year (365 days)\n\n    @param jy Jalaali calendar year (-61 to 3177)\n    @returns number of years since the last leap year (0 to 4)\n */\nfunction jalCalLeap(jy) {\n  const bl = breaks.length\n  let jp = breaks[0],\n    jm,\n    jump,\n    leap,\n    n,\n    i\n\n  if (jy < jp || jy >= breaks[bl - 1]) {\n    throw new Error('Invalid Jalaali year ' + jy)\n  }\n\n  for (i = 1; i < bl; i += 1) {\n    jm = breaks[i]\n    jump = jm - jp\n    if (jy < jm) {\n      break\n    }\n    jp = jm\n  }\n  n = jy - jp\n\n  if (jump - n < 6) {\n    n = n - jump + div(jump + 4, 33) * 33\n  }\n  leap = mod(mod(n + 1, 33) - 1, 4)\n  if (leap === -1) {\n    leap = 4","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/quasarframework/quasar/blob/4841521b5f635a971eb9e2710e5542efd194691b/ui/src/utils/date/private.persian.js#L46-L82","documentation":"Quasar's Persian (Jalaali) calendar utilities, ported from jalaali-js, only support Jalaali years -61 through 3177 (the range covered by the 33-year cycle 'breaks' table). jalCalLeap() validates its input against that table and throws when the year falls outside it. It is reached indirectly via jalaaliMonthLength(), which calls it for month 12 length checks.","triggerScenarios":"Calling jalaaliMonthLength(jy, 12) (or any code path reaching jalCalLeap) with jy < -61 or jy >= 3178, e.g. jalaaliMonthLength(3178, 12) or jalaaliMonthLength(-62, 5).","commonSituations":"Computing Persian dates from user input without bounds checks; generating date pickers across extreme ranges; arithmetic on Jalaali years that overflows the supported era (e.g. adding centuries to year 3177).","solutions":["Validate the year before calling: throw/handle when jy < -61 || jy > 3177.","Clamp or normalize out-of-range years to the supported -61..3177 window.","If you need dates outside this era, use a different calendar library with wider coverage instead of Quasar's Persian utils."],"exampleFix":"// before\nconst days = jalaaliMonthLength(jy, 12)\n\n// after\nif (jy < -61 || jy > 3177) {\n  throw new RangeError(`Jalaali year ${jy} outside supported range -61..3177`)\n}\nconst days = jalaaliMonthLength(jy, 12)","handlingStrategy":"validation","validationCode":"function isValidJalaaliYear(jy) {\n  return typeof jy === 'number' && Number.isInteger(jy) && jy >= -61 && jy <= 3177\n}\nif (!isValidJalaaliYear(jy)) throw new RangeError(`Unsupported Jalaali year: ${jy}`)","typeGuard":"function isValidJalaaliYear(jy) {\n  return typeof jy === 'number' && Number.isInteger(jy) && jy >= -61 && jy <= 3177\n}","tryCatchPattern":"let days\ntry {\n  days = jalaaliMonthLength(jy, 12)\n} catch (err) {\n  if (/Invalid Jalaali year/.test(err.message)) {\n    days = 29 // fallback for out-of-range years\n  } else throw err\n}","preventionTips":["Always bound-check Persian years against -61..3177 before calendar math.","Sanitize user-entered years (reject NaN, non-integers, absurd values) at the form level.","Add a unit test covering the range edges (jy = -61, 3177, -62, 3178)."],"tags":["persian-calendar","date","range-check"],"backgroundTag":"jalaali-year-out-of-range","analyzedSha":"4841521b5f635a971eb9e2710e5542efd194691b","analyzedAt":"2026-08-30T01:13:14.944Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}