Budibase/budibase · error · Error

Invalid automation CRON "${cronExp}" - ${validation.err.join

Error message

Invalid automation CRON "${cronExp}" - ${validation.err.join(", ")}

What it means

`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.

Source

Thrown at packages/server/src/automations/utils.ts:298

  automation: Automation
  clearedRepeatableJobs: number
}> {
  const trigger = automation ? automation.definition.trigger : null
  let enabled = false

  let clearedRepeatableJobs = 0

  if (!trigger || automation.disabled || isRebootTrigger(automation)) {
    return { enabled, automation, clearedRepeatableJobs }
  }

  if (isCronTrigger(trigger)) {
    const inputs = trigger.inputs as CronTriggerInputs
    const cronExp = inputs.cron || ""
    const timezone = inputs.timezone
    const validation = helpers.cron.validate(cronExp)
    if (!validation.valid) {
      throw new Error(
        `Invalid automation CRON "${cronExp}" - ${validation.err.join(", ")}`
      )
    }

    const existingJobId = trigger.cronJobId
    if (existingJobId && isLegacyRepeatableJobId(existingJobId)) {
      const removedJobs = await removeLegacyRepeatableJob(
        existingJobId,
        appId,
        automation._id
      )
      clearedRepeatableJobs += removedJobs
    }
    const jobId =
      !existingJobId || isLegacyRepeatableJobId(existingJobId)
        ? `${appId}_cron_${utils.newid()}`
        : existingJobId
    await automationQueue.add(

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Open the cron automation in the builder and set a valid 5-field cron expression, e.g. "0 * * * *".
  2. If the expression looks right, check the validator's specific err list in the error message (appended after the dash) and fix that component.
  3. Check trigger.inputs in the CouchDB app document; ensure inputs.cron is a non-empty string and inputs.timezone is valid.
  4. Re-deploy the app after fixing so enableCronOrEmailTrigger re-runs and schedules the job.

Example fix

// before
{ "type": "CRON", "inputs": { "cron": "every 5 minutes" } }
// after
{ "type": "CRON", "inputs": { "cron": "*/5 * * * *", "timezone": "Europe/London" } }
Defensive patterns

Strategy: validation

Validate before calling

import cron from "@budibase/string-templates/helpers" // or your cron validator
const inputs = trigger.inputs as { cron?: string; timezone?: string }
const cronExp = inputs.cron || ""
const v = helpers.cron.validate(cronExp)
if (!v.valid) throw new Error(`Fix cron '${cronExp}': ${v.err.join(", ")}`)

Try / catch

try {
  await deployApp(appId)
} catch (err) {
  if (err.message.startsWith("Invalid automation CRON")) {
    const cronExp = err.message.match(/"([^"]*)"/)?.[1]
    console.error(`Cron trigger '${cronExp}' is invalid; fix in builder and redeploy`)
  }
  throw err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/6ffc10dd7243ad59. Report an issue: GitHub.