langchain-ai/deepagents · error · CronJobError

repeat cap is only valid for recurring jobs

Error message

repeat cap is only valid for recurring jobs

What it means

create_job raises this CronJobError when a one-shot schedule ('in ...') is combined with a repeat cap (repeat_times is not None). Repeat caps only make sense for recurring ('every ...') jobs, since a one-shot job runs exactly once and can never repeat; the library rejects the contradictory configuration up front.

Source

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

    ) -> CronJob:
        """Create and persist a cron job.

        Args:
            prompt: Prompt passed to the agent when the job fires.
            schedule: Job schedule.
            origin: Conversation that receives results.
            name: Human-readable label.
            repeat_times: Optional cap for recurring jobs.
            now: Creation time override for deterministic tests.

        Returns:
            Created job record.
        """
        current = _coerce_utc(now)
        repeat = CronRepeat(times=repeat_times)
        if schedule.kind == "one_shot" and repeat_times is not None:
            msg = "repeat cap is only valid for recurring jobs"
            raise CronJobError(msg)
        job = CronJob(
            id=uuid.uuid4().hex[:12],
            assistant_id=self.assistant_id,
            name=name,
            prompt=prompt,
            schedule=schedule,
            repeat=repeat,
            enabled=True,
            created_at=current,
            next_run_at=schedule.next_after(current),
            last_run_at=None,
            last_status=None,
            last_error=None,
            origin=origin,
        )
        jobs = [*self.list_jobs(), job]
        self._write_jobs(jobs)
        return job

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass repeat_times=None when the schedule is one-shot
  2. Only set repeat_times when schedule.kind == 'recurring'
  3. Branch on the parsed schedule's kind before calling create_job
  4. Catch CronJobError and drop the cap (retry with repeat_times=None) if the schedule is one-shot

Example fix

// before
job = store.create_job(name="ping", prompt="...", schedule=CronSchedule.parse("in 30m"), repeat_times=3)
// after
job = store.create_job(name="ping", prompt="...", schedule=CronSchedule.parse("in 30m"), repeat_times=None)
# caps only for recurring:
job = store.create_job(name="ping", prompt="...", schedule=CronSchedule.parse("every 15m"), repeat_times=3)
Defensive patterns

Strategy: try-catch

Validate before calling

def is_recurring(schedule) -> bool:
    return getattr(schedule, "kind", None) == "recurring"

safe_repeat_times = repeat_times if is_recurring(schedule) else None
job = store.create_job(..., schedule=schedule, repeat_times=safe_repeat_times)

Type guard

def is_recurring_schedule(schedule: object) -> bool:
    return getattr(schedule, "kind", None) == "recurring"

Try / catch

try:
    job = store.create_job(..., schedule=schedule, repeat_times=repeat_times)
except CronJobError as exc:
    if "repeat cap" in str(exc):
        job = store.create_job(..., schedule=schedule, repeat_times=None)
    else:
        raise

Prevention

When it happens

Trigger: Calling create_job(name=..., prompt=..., schedule=<one_shot CronSchedule>, repeat_times=3). Also constructing via parse('in 30m') while passing a non-None repeat_times from a shared code path that always forwards a cap.

Common situations: A UI form that always shows a repeat-count field regardless of schedule type; refactors where a default repeat_times=1 leaked into one-shot creation; misreading None (unlimited) vs 0 as the way to say 'no cap' and passing a number alongside a one-shot schedule.

Related errors


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