{"record":{"id":"e4b9c2ff6888f7b3","repo":"denoland/deno","slug":"invalid-cron-schedule-start-start-end-end","errorCode":null,"errorMessage":"Invalid cron schedule: start=${start}, end=${end}, every=${every}","messagePattern":"Invalid cron schedule: start=(.+?), end=(.+?), every=(.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/cron/01_cron.ts","lineNumber":53,"sourceCode":"    const { exact } = value as { exact: number | number[] };\n    if (exact === undefined) {\n      const { start, end, every } = value as {\n        start?: number;\n        end?: number;\n        every?: number;\n      };\n      if (start !== undefined && end !== undefined && every !== undefined) {\n        return start + \"-\" + end + \"/\" + every;\n      } else if (start !== undefined && end !== undefined) {\n        return start + \"-\" + end;\n      } else if (start !== undefined && every !== undefined) {\n        return start + \"/\" + every;\n      } else if (start !== undefined) {\n        return start + \"/1\";\n      } else if (end === undefined && every !== undefined) {\n        return \"*/\" + every;\n      } else {\n        throw new TypeError(\n          `Invalid cron schedule: start=${start}, end=${end}, every=${every}`,\n        );\n      }\n    } else {\n      if (typeof exact === \"number\") {\n        return NumberPrototypeToString(exact);\n      } else {\n        return ArrayPrototypeJoin(exact, \",\");\n      }\n    }\n  }\n}\n\nfunction parseScheduleToString(\n  schedule: string | Deno.CronSchedule,\n): string {\n  if (typeof schedule === \"string\") {\n    return schedule;","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/cron/01_cron.ts#L35-L71","documentation":"Deno.CronSchedule field objects are converted by formatToCronSchedule. Valid shapes: {exact: n}, {exact: [...]}, {every} alone, {start}, {start, every}, {start, end}, {start, end, every}. A field with end but no start (with or without every) has no cron representation and throws.","triggerScenarios":"Deno.cron('n', { minute: { end: 10 } }) or Deno.cron('n', { minute: { end: 10, every: 2 } }) — end without start and exact undefined.","commonSituations":"Writing schedule objects from half-remembered syntax; assuming end alone means 'up to the end of the range'.","solutions":["Add start: { minute: { start: 0, end: 10 } }.","Use every alone ({ minute: { every: 5 } }) or exact when no range is needed."],"exampleFix":"// before\nDeno.cron('n', { hour: { end: 12 } }, fn);\n// after\nDeno.cron('n', { hour: { start: 0, end: 12 } }, fn);","handlingStrategy":"type-guard","validationCode":"for (const [field, spec] of Object.entries(schedule)) {\n  if (typeof spec === 'object' && spec.exact === undefined && spec.end !== undefined && spec.start === undefined) {\n    throw new Error(`cron field ${field} has end without start`);\n  }\n}","typeGuard":"function isValidCronField(v: unknown): boolean {\n  if (typeof v === 'number') return true;\n  if (typeof v !== 'object' || v === null) return false;\n  const r = v as Record<string, unknown>;\n  if (r.exact !== undefined) return true;\n  if (r.end !== undefined && r.start === undefined) return false; // end-only throws\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Type schedule fields as { exact?: number | number[]; start?: number; end?: number; every?: number } and remember end requires start.","Prefer the cron string form ('*/5 * * * *') when the schedule is static — it cannot hit this branch."],"tags":["cron","scheduling","validation","typescript"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}