{"record":{"id":"6ffc10dd7243ad59","repo":"Budibase/budibase","slug":"invalid-automation-cron-cronexp-validatio","errorCode":null,"errorMessage":"Invalid automation CRON \"${cronExp}\" - ${validation.err.join(\", \")}","messagePattern":"Invalid automation CRON \"(.+?)\" - (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/automations/utils.ts","lineNumber":298,"sourceCode":"  automation: Automation\n  clearedRepeatableJobs: number\n}> {\n  const trigger = automation ? automation.definition.trigger : null\n  let enabled = false\n\n  let clearedRepeatableJobs = 0\n\n  if (!trigger || automation.disabled || isRebootTrigger(automation)) {\n    return { enabled, automation, clearedRepeatableJobs }\n  }\n\n  if (isCronTrigger(trigger)) {\n    const inputs = trigger.inputs as CronTriggerInputs\n    const cronExp = inputs.cron || \"\"\n    const timezone = inputs.timezone\n    const validation = helpers.cron.validate(cronExp)\n    if (!validation.valid) {\n      throw new Error(\n        `Invalid automation CRON \"${cronExp}\" - ${validation.err.join(\", \")}`\n      )\n    }\n\n    const existingJobId = trigger.cronJobId\n    if (existingJobId && isLegacyRepeatableJobId(existingJobId)) {\n      const removedJobs = await removeLegacyRepeatableJob(\n        existingJobId,\n        appId,\n        automation._id\n      )\n      clearedRepeatableJobs += removedJobs\n    }\n    const jobId =\n      !existingJobId || isLegacyRepeatableJobId(existingJobId)\n        ? `${appId}_cron_${utils.newid()}`\n        : existingJobId\n    await automationQueue.add(","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/automations/utils.ts#L280-L316","documentation":"`enableCronOrEmailTrigger` schedules cron automations when an app is deployed or the worker rehydrates jobs. It validates the trigger's cron expression with `helpers.cron.validate`; if the expression is invalid (or empty, since cronExp defaults to \"\"), it throws with the expression and the validator's error list. Empty cron commonly results from inputs never being filled in.","triggerScenarios":"Deploying an app (initDeployedApp) or restarting the worker (rehydrateScheduledTriggers) while a cron trigger has an invalid or empty `inputs.cron` (e.g. \"* * *\" or \"every monday\"); a timezone-bearing trigger whose cron string was hand-edited to an unsupported syntax.","commonSituations":"User typed a human-readable schedule instead of a cron expression; app imported from an export where cron inputs were stripped; upgrade changes in the cron parser making a previously accepted expression invalid; timezone inputs left blank combined with malformed cron.","solutions":["Open the cron automation in the builder and set a valid 5-field cron expression, e.g. \"0 * * * *\".","If the expression looks right, check the validator's specific err list in the error message (appended after the dash) and fix that component.","Check trigger.inputs in the CouchDB app document; ensure inputs.cron is a non-empty string and inputs.timezone is valid.","Re-deploy the app after fixing so enableCronOrEmailTrigger re-runs and schedules the job."],"exampleFix":"// before\n{ \"type\": \"CRON\", \"inputs\": { \"cron\": \"every 5 minutes\" } }\n// after\n{ \"type\": \"CRON\", \"inputs\": { \"cron\": \"*/5 * * * *\", \"timezone\": \"Europe/London\" } }","handlingStrategy":"validation","validationCode":"import cron from \"@budibase/string-templates/helpers\" // or your cron validator\nconst inputs = trigger.inputs as { cron?: string; timezone?: string }\nconst cronExp = inputs.cron || \"\"\nconst v = helpers.cron.validate(cronExp)\nif (!v.valid) throw new Error(`Fix cron '${cronExp}': ${v.err.join(\", \")}`)","typeGuard":null,"tryCatchPattern":"try {\n  await deployApp(appId)\n} catch (err) {\n  if (err.message.startsWith(\"Invalid automation CRON\")) {\n    const cronExp = err.message.match(/\"([^\"]*)\"/)?.[1]\n    console.error(`Cron trigger '${cronExp}' is invalid; fix in builder and redeploy`)\n  }\n  throw err\n}","preventionTips":["Always fill the cron field in CRON triggers — an empty value fails validation.","Test the expression with a cron validator (5 fields) before deploying.","Avoid hand-editing cron strings in app exports; use the builder UI.","Re-run the deploy/rehydrate after fixing so the job gets scheduled."],"tags":["automation","cron","scheduling","trigger","validation"],"backgroundTag":"invalid-cron-expression","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}