{"record":{"id":"be784acd3da9c014","repo":"jlcodes99/cockpit-tools","slug":"invalid-crontab-number","errorCode":"invalid_crontab_number","errorMessage":"invalid_crontab_number","messagePattern":"invalid_crontab_number","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/pages/WakeupTasksPage.tsx","lineNumber":442,"sourceCode":"interface ParsedCronField {\n  values: Set<number>;\n  wildcard: boolean;\n}\n\ninterface ParsedCrontab {\n  minute: ParsedCronField;\n  hour: ParsedCronField;\n  dayOfMonth: ParsedCronField;\n  month: ParsedCronField;\n  dayOfWeek: ParsedCronField;\n}\n\nconst normalizeCrontabDayOfWeek = (value: number) => (value === 7 ? 0 : value);\n\nconst parseCrontabNumber = (raw: string): number => {\n  const parsed = Number.parseInt(raw.trim(), 10);\n  if (Number.isNaN(parsed)) {\n    throw new Error('invalid_crontab_number');\n  }\n  return parsed;\n};\n\nconst validateCrontabValue = (\n  value: number,\n  min: number,\n  max: number,\n  normalizeDayOfWeek: boolean,\n) => {\n  if (normalizeDayOfWeek && value === 7) return;\n  if (value < min || value > max) {\n    throw new Error('crontab_value_out_of_range');\n  }\n};\n\nconst insertCrontabRange = (\n  target: Set<number>,","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/pages/WakeupTasksPage.tsx#L424-L460","documentation":"parseCrontabNumber in WakeupTasksPage parses a crontab field token with parseInt and throws Error('invalid_crontab_number') when the token is not a valid integer. It is part of the page's custom cron-expression parser used when building wakeup-task schedules.","triggerScenarios":"A crontab expression field (minute/hour/day/month/day-of-week, or a range/step component) contains a token that parseInt cannot convert to a number — e.g. '*', letters, '1-*/2' components reaching the numeric path, or empty strings from double commas.","commonSituations":"User hand-edits the cron string into the input and types invalid characters; a saved expression from an older version or another scheduler uses syntax this parser doesn't accept (e.g. '*', 'L', names like 'MON'); copy-pasted expressions with stray whitespace/symbols.","solutions":["Correct the crontab expression so every field is a valid integer or supported range/step syntax the parser accepts.","Use the UI's field pickers instead of free-typing the cron string to generate valid values.","Validate the expression with the same parse logic before saving to catch the bad token early.","Catch the parse error and show which field/token failed so the user can fix it."],"exampleFix":"// before\nparseCronExpression('30 * * * MON'); // throws invalid_crontab_number\n// after\nparseCronExpression('30 * * * 1'); // day-of-week as number","handlingStrategy":"validation","validationCode":"const isValidCronToken = (raw: string) =>\n  /^\\d+$/.test(raw.trim()) && !Number.isNaN(Number.parseInt(raw.trim(), 10));\n// run over every numeric token before parsing/saving the expression","typeGuard":"const isNumericToken = (raw: string): raw is `${number}` =>\n  /^\\d+$/.test(raw.trim());","tryCatchPattern":"try {\n  const expr = parseCronExpression(input);\n  save(expr);\n} catch (e) {\n  if (e.message === 'invalid_crontab_number') {\n    showFieldError('cron', '每一段必须是有效数字（不支持 * / 名称等语法）');\n    return;\n  }\n  throw e;\n}","preventionTips":["Prefer the UI field pickers over free-text cron editing.","Reject or expand unsupported syntax ('*', names like MON) before parse.","Validate the whole expression with the app's own parser before persisting."],"tags":["cron","parsing","validation"],"backgroundTag":"invalid-crontab-syntax","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}