{"record":{"id":"352526a545bfc979","repo":"paperclipai/paperclip","slug":"empty-element-in-cron-spec-name-field","errorCode":null,"errorMessage":"Empty element in cron ${spec.name} field","messagePattern":"Empty element in cron (.+?) field","errorType":"validation","errorClass":"Error","httpStatus":422,"severity":"error","filePath":"server/src/services/cron.ts","lineNumber":79,"sourceCode":"// Parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a single cron field token (e.g. `\"5\"`, `\"1-3\"`, `\"* /10\"`, `\"1,3,5\"`).\n *\n * @returns Sorted deduplicated array of matching integer values within bounds.\n * @throws {Error} on invalid syntax or out-of-range values.\n */\nfunction parseField(token: string, spec: FieldSpec): number[] {\n  const values = new Set<number>();\n\n  // Split on commas first — each part can be a value, range, or step\n  const parts = token.split(\",\");\n\n  for (const part of parts) {\n    const trimmed = part.trim();\n    if (trimmed === \"\") {\n      throw new Error(`Empty element in cron ${spec.name} field`);\n    }\n\n    // Check for step syntax: \"X/S\" where X is \"*\" or a range or a number\n    const slashIdx = trimmed.indexOf(\"/\");\n    if (slashIdx !== -1) {\n      const base = trimmed.slice(0, slashIdx);\n      const stepStr = trimmed.slice(slashIdx + 1);\n      const step = parseInt(stepStr, 10);\n      if (isNaN(step) || step <= 0) {\n        throw new Error(\n          `Invalid step \"${stepStr}\" in cron ${spec.name} field`,\n        );\n      }\n\n      let rangeStart = spec.min;\n      let rangeEnd = spec.max;\n\n      if (base === \"*\") {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/cron.ts#L61-L97","documentation":"Token guard in the cron parser's parseField: after splitting a field on commas, one element trims to the empty string (e.g. \"1,,5\" or a trailing comma). An empty list element cannot denote a value, range, or step, so parsing aborts with the field name (minute/hour/dom/month/dow).","triggerScenarios":"Thrown at server/src/services/cron.ts:79 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove empty elements (e.g. double commas) from the named cron field."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}