{"record":{"id":"7ac42d23b361d426","repo":"stablyai/orca","slug":"hermes-cron-requires-a-schedule","errorCode":null,"errorMessage":"Hermes cron requires a schedule.","messagePattern":"Hermes cron requires a schedule\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/automations/external-manager.ts","lineNumber":423,"sourceCode":"\nfunction normalizeHermesCronMutationInput(input: ExternalAutomationCreateInput): {\n  name: string\n  prompt: string\n  schedule: string\n  workdir: string | null\n} {\n  if (input.provider !== 'hermes') {\n    throw new Error('Only Hermes cron creation and editing are supported.')\n  }\n  const name = input.name.trim()\n  const prompt = input.prompt.trim()\n  const schedule = input.schedule.trim()\n  const workdir = input.workdir?.trim() || null\n  if (!prompt) {\n    throw new Error('Hermes cron requires a prompt.')\n  }\n  if (!schedule) {\n    throw new Error('Hermes cron requires a schedule.')\n  }\n  return {\n    name: name || prompt.slice(0, 50).trim() || 'Hermes cron',\n    prompt,\n    schedule,\n    workdir\n  }\n}\n\nfunction hermesCronCreateArgs(input: {\n  name: string\n  prompt: string\n  schedule: string\n  workdir: string | null\n}): string[] {\n  const args = [\n    'cron',\n    'create',","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/automations/external-manager.ts#L405-L441","documentation":"Thrown by normalizeHermesCronMutationInput() after trimming when input.schedule is empty (and prompt already passed). A Hermes cron requires a schedule expression (cron syntax) to run. The guard does not validate cron grammar here — only non-emptiness.","triggerScenarios":"Creating/editing a Hermes cron with a blank/whitespace-only schedule; a schedule picker that returned undefined or ''; a default cron string that failed to load.","commonSituations":"User leaves the schedule field empty; a cron-picker UI bug returns ''; a template/import omitted the schedule field.","solutions":["Default or require a schedule in the form (e.g. '0 * * * *') and validate non-empty before submitting.","Coerce undefined to '' and surface a validation error instead of calling the API.","After non-empty passes, also validate the cron expression parses to catch malformed schedules early."],"exampleFix":"// before\ncreateExternalAutomation({ provider: 'hermes', prompt: 'run x', schedule: '', ... }) // throws\n\n// after\nconst schedule = rawSchedule.trim() || '0 * * * *'\nif (!isValidCron(schedule)) throw new UserError('Invalid schedule.')\ncreateExternalAutomation({ provider: 'hermes', prompt: 'run x', schedule, ... })","handlingStrategy":"validation","validationCode":"function isNonEmptySchedule(v: unknown): boolean {\n  return typeof v === 'string' && v.trim().length > 0\n}\n\nif (input.provider === 'hermes' && !isNonEmptySchedule(input.schedule)) {\n  throw new UserError('Hermes cron needs a schedule.')\n}\ncreateExternalAutomation(input)","typeGuard":"function isNonEmptySchedule(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0\n}","tryCatchPattern":"try {\n  await createExternalAutomation(input)\n} catch (e) {\n  if ((e as Error).message === 'Hermes cron requires a schedule.') {\n    throw new UserError('Please enter a cron schedule for the job.')\n  }\n  throw e\n}","preventionTips":["Default the schedule field to a sane cron (e.g. '0 * * * *') and validate non-empty before submit.","Run a cron-grammar validation (beyond non-empty) to catch malformed schedules early.","For programmatic callers, assert input.schedule?.trim() is truthy upstream."],"tags":["automations","hermes","validation","cron","input"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}