langchain-ai/deepagents · error · CronJobError

cron schedules must be at least 1 minute

Error message

cron schedules must be at least 1 minute

What it means

`CronSchedule.__post_init__` validates that a schedule's granularity (`minutes`) is at least `MIN_GRANULARITY_MINUTES` (1 minute). Cron-like schedules finer than one minute are unsupported by the job scheduler, so constructing a `CronSchedule` with a smaller interval raises `CronJobError` at dataclass construction time.

Source

Thrown at libs/talon/deepagents_talon/cron/jobs.py:129

@dataclass(frozen=True, slots=True)
class CronSchedule:
    """Minute-granularity schedule for a cron job.

    Args:
        kind: Whether the schedule is one-shot or recurring.
        minutes: Delay or interval in minutes.
        display: Human-readable schedule text supplied by the agent.
    """

    kind: ScheduleKind
    minutes: int
    display: str

    def __post_init__(self) -> None:
        """Validate schedule granularity."""
        if self.minutes < MIN_GRANULARITY_MINUTES:
            msg = "cron schedules must be at least 1 minute"
            raise CronJobError(msg)

    @classmethod
    def parse(cls, value: str) -> CronSchedule:
        """Parse a supported schedule string.

        Args:
            value: Schedule text such as `in 30m` or `every 15m`.

        Returns:
            Parsed schedule.

        Raises:
            CronJobError: If the schedule string is unsupported.
        """
        text = " ".join(value.strip().lower().split())
        if text.startswith("in "):
            return cls(kind="one_shot", minutes=_parse_duration_minutes(text[3:]), display=value)
        if text.startswith("every "):

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use a schedule of at least 1 minute, e.g. CronSchedule(minutes=1) or a 'every minute' schedule string.
  2. If you need sub-minute triggering, implement it outside CronSchedule (e.g. a loop in your own scheduler) or batch work into minute-granularity jobs.
  3. Check the parsed value: if parsing user input, clamp/round the interval up to 1 minute before constructing the dataclass.

Example fix

# before
schedule = CronSchedule(minutes=0, display='every 0 minutes')
# after
schedule = CronSchedule(minutes=1, display='every minute')
Defensive patterns

Strategy: validation

Validate before calling

def clamp_schedule_minutes(minutes: int, min_minutes: int = 1) -> int:
    return max(minutes, min_minutes)

schedule = CronSchedule(minutes=clamp_schedule_minutes(requested_minutes), display=display)

Type guard

def schedule_allowed(minutes: int) -> bool:
    return minutes >= 1

Try / catch

try:
    schedule = CronSchedule.parse(user_input)
except CronJobError as exc:
    logging.warning("invalid schedule %r: %s", user_input, exc)
    schedule = CronSchedule(minutes=1, display="every minute")

Prevention

When it happens

Trigger: Creating `CronSchedule(minutes=0)` or a negative value directly, or parsing a schedule string that resolves to sub-minute intervals via `CronSchedule.parse`.

Common situations: Users porting standard cron expressions that allow `* * * * *` variants or second-level schedulers (e.g. every 30s from other tools) into Talon; programmatically generating schedules with an off-by-one interval.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/8c0a70b2dcb35a06. Report an issue: GitHub.