langchain-ai/deepagents · error · CronJobError

schedule duration must use 'm' for minutes or 'h' for hours

Error message

schedule duration must use 'm' for minutes or 'h' for hours

What it means

CronJobError raised by `_parse_duration_minutes` in libs/talon/deepagents_talon/cron/jobs.py when parsing a schedule duration string that does not end in 'm' (minutes) or 'h' (hours). The library only accepts these two unit suffixes so schedule granularity stays unambiguous and minute-based. Any other suffix (e.g. 's', 'd', 'w') or no suffix at all is rejected.

Source

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

    next_run_at = cast("datetime", job.next_run_at)
    interval = timedelta(minutes=job.schedule.minutes)
    while next_run_at <= now:
        next_run_at += interval
    return replace(job, repeat=repeat, next_run_at=next_run_at)


def _parse_duration_minutes(value: str) -> int:
    parts = value.split()
    if len(parts) != 1:
        msg = "schedule duration must be a single value such as '30m'"
        raise CronJobError(msg)
    text = parts[0]
    if text.endswith("m"):
        return _positive_int(text[:-1])
    if text.endswith("h"):
        return _positive_int(text[:-1]) * 60
    msg = "schedule duration must use 'm' for minutes or 'h' for hours"
    raise CronJobError(msg)


def _positive_int(value: str) -> int:
    if not value.isdecimal():
        msg = "schedule duration must be a positive integer"
        raise CronJobError(msg)
    number = int(value)
    if number < MIN_GRANULARITY_MINUTES:
        msg = "schedule duration must be at least 1 minute"
        raise CronJobError(msg)
    return number


def _same_origin_scope(left: CronOrigin, right: CronOrigin) -> bool:
    return left.conversation_id == right.conversation_id and left.channel == right.channel


def _coerce_utc(value: datetime | None = None) -> datetime:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Append a supported unit suffix: use 'm' for minutes (e.g. '30m') or 'h' for hours (e.g. '2h').
  2. Convert other units yourself before passing: seconds to minutes, days to hours (e.g. '2d' -> '48h').
  3. Ensure the string is a plain duration token with no extra text, spaces, or compound parts (e.g. '1h30m' is not accepted).

Example fix

// before
parse("90min", ...)
parse("2d", ...)
// after
parse("90m", ...)
parse("48h", ...)
Defensive patterns

Strategy: validation

Validate before calling

import re
_DURATION_RE = re.compile(r"^\d+(m|h)$")
def validate_schedule_duration(text: str) -> bool:
    return bool(_DURATION_RE.match(text.strip()))

Type guard

def is_valid_duration(text: str) -> bool:
    return isinstance(text, str) and text.endswith(("m", "h")) and text[:-1].isdecimal()

Try / catch

from deepagents_talon.cron.jobs import CronJobError
try:
    job = parse(schedule)
except CronJobError as exc:
    logger.error("invalid schedule %r: %s", schedule, exc)
    raise ValueError(f"bad schedule {schedule!r}") from exc

Prevention

When it happens

Trigger: Calling `parse` (via the cron job creation API) with a schedule duration like '30s', '2d', '45', or '1m30s'. The suffix check `text.endswith('m')` / `endswith('h')` fails and the error is raised.

Common situations: Developers copying cron-style syntax that supports seconds or days; passing a bare number without a unit; writing durations like '90min' or '1hr' with long unit names; migrating configs from other schedulers that accept 'd' or 's'.

Related errors


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