{"record":{"id":"bd1381da7df02313","repo":"actualbudget/actual","slug":"date-is-required","errorCode":null,"errorMessage":"Date is required","messagePattern":"Date is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/schedules/app.ts","lineNumber":336,"sourceCode":"  await db.moveSchedule(id, targetId);\n  return {};\n}\n\nexport async function createSchedule({\n  schedule = null,\n  conditions = [],\n}: {\n  schedule?: Partial<ScheduleEntity> | null;\n  conditions?: RuleConditionEntity[];\n} = {}): Promise<ScheduleEntity['id']> {\n  const scheduleId = schedule?.id || uuidv4();\n\n  const { date: dateCond } = extractScheduleConds(conditions);\n  if (dateCond == null) {\n    throw new Error('A date condition is required to create a schedule');\n  }\n  if (dateCond.value == null) {\n    throw new Error('Date is required');\n  }\n\n  const nextDate = getNextDate(dateCond);\n  const nextDateRepr = nextDate ? toDateRepr(nextDate) : null;\n  const scheduleFields = schedule && {\n    ...schedule,\n    name: normalizeScheduleName(schedule.name),\n  };\n  if (scheduleFields) {\n    if (scheduleFields.name) {\n      if (await checkIfScheduleExists(scheduleFields.name, scheduleId)) {\n        throw new Error('Cannot create schedules with the same name');\n      }\n    }\n  }\n\n  // Create the rule here based on the info\n  const ruleId = await insertRule({","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/schedules/app.ts#L318-L354","documentation":"After confirming a date condition exists, `createSchedule` checks `dateCond.value`. A date condition with a null/undefined value (a date condition with no actual date) cannot produce a next date, so creation is rejected.","triggerScenarios":"Calling `createSchedule` with a condition `{ field: 'date', op: 'isapprox' }` but no `value` (or `value: null`), e.g. building the schedule form payload before the user picked a date.","commonSituations":"UI/API flows that submit the schedule before the date picker resolves; integrations serializing conditions where the recurring descriptor was dropped.","solutions":["Set `value` on the date condition to a valid date string or recurring descriptor before calling createSchedule","Pre-validate conditions: `dateCond != null && dateCond.value != null`","Use `getNextDate`/the shared schedule helpers to sanity-check the value parses"],"exampleFix":"// before\n{ field: 'date', op: 'isapprox', value: null }\n// after\n{ field: 'date', op: 'isapprox', value: { frequency: 'monthly', start: '2026-02-01' } }","handlingStrategy":"validation","validationCode":"const dateCond = conditions.find(c => c.field === 'date');\nif (!dateCond || dateCond.value == null) {\n  throw new Error('Date condition must have a value before createSchedule');\n}\nawait createSchedule({ conditions });","typeGuard":"function hasDateValue(c) {\n  return c.field === 'date' && c.value != null &&\n    (typeof c.value === 'string' || typeof c.value === 'object');\n}","tryCatchPattern":"try {\n  const id = await createSchedule({ conditions });\n} catch (e) {\n  if (e.message === 'Date is required') {\n    logger.error('Date condition has no value', conditions);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Disable schedule submission in UIs until the date value is set","Check value != null on the date condition as a precondition","Serialize recurring descriptors fully (don't drop nested objects)","Add schema validation (zod/etc.) on schedule payloads at API boundaries"],"tags":["schedule","validation","missing-value"],"backgroundTag":"missing-date-condition","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}