{"record":{"id":"682208d793fc5af3","repo":"langchain-ai/deepagents","slug":"repeat-completed-count-cannot-be-negative","errorCode":null,"errorMessage":"repeat completed count cannot be negative","messagePattern":"repeat completed count cannot be negative","errorType":"validation","errorClass":"CronJobError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/cron/jobs.py","lineNumber":203,"sourceCode":"class CronRepeat:\n    \"\"\"Optional cap for recurring cron jobs.\n\n    Args:\n        times: Maximum scheduled attempts, or `None` for unlimited recurrence.\n        completed: Number of intervals already claimed for execution.\n    \"\"\"\n\n    times: int | None = None\n    completed: int = 0\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate repeat cap values.\"\"\"\n        if self.times is not None and self.times < 1:\n            msg = \"repeat cap must be at least 1\"\n            raise CronJobError(msg)\n        if self.completed < 0:\n            msg = \"repeat completed count cannot be negative\"\n            raise CronJobError(msg)\n\n    def claim(self) -> CronRepeat:\n        \"\"\"Return repeat state after claiming one scheduled attempt.\n\n        Returns:\n            Updated repeat state.\n        \"\"\"\n        return replace(self, completed=self.completed + 1)\n\n    @property\n    def exhausted(self) -> bool:\n        \"\"\"Whether the repeat cap has been reached.\"\"\"\n        return self.times is not None and self.completed >= self.times\n\n    def to_dict(self) -> CronRepeatDict:\n        \"\"\"Serialize this repeat state for disk storage.\n\n        Returns:","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/cron/jobs.py#L185-L221","documentation":"CronRepeat.__post_init__ enforces that the completed attempt counter is non-negative; constructing a CronRepeat with completed < 0 raises this CronJobError at instantiation. The completed count is internal bookkeeping for how many runs of a capped recurring job have finished, so a negative value indicates corrupted or miscalculated state.","triggerScenarios":"Constructing CronRepeat(times=5, completed=-1) (or any negative completed) directly, deserializing persisted job records whose stored completed count is negative, or computing completed via subtraction that underflows.","commonSituations":"Hand-editing or migrating persisted cron job JSON where the counter went negative; restoring from a backup with corrupt state; arithmetic bugs like completed - fetched_count when fetched exceeds completed.","solutions":["Fix the persisted/computed state so completed >= 0 before constructing CronRepeat","Clamp with max(0, value) when reconstructing from external data","Catch CronJobError during deserialization and reset the record's repeat state to CronRepeat(times=...)","Audit the code path that decrements completed to ensure it never subtracts more than available"],"exampleFix":"// before\nrepeat = CronRepeat(times=3, completed=done - fetched)  # may go negative\n// after\nrepeat = CronRepeat(times=3, completed=max(0, done - fetched))","handlingStrategy":"validation","validationCode":"def can_construct_repeat(times, completed) -> bool:\n    return completed >= 0 and (times is None or times >= 1)\n\nif not can_construct_repeat(times, completed):\n    completed = max(0, completed)  # clamp before constructing","typeGuard":"def has_valid_completed(value: object) -> bool:\n    return isinstance(value, int) and not isinstance(value, bool) and value >= 0","tryCatchPattern":"try:\n    repeat = CronRepeat(times=t, completed=stored_completed)\nexcept CronJobError:\n    repeat = CronRepeat(times=t, completed=0)  # reset corrupt counter","preventionTips":["Clamp counters with max(0, value) when deserializing persisted state","Never subtract unvalidated external counts from completed","Treat negative counters as corrupt data and reset rather than propagate","Validate state after migrations or manual edits of persisted job records"],"tags":["validation","cron","state"],"backgroundTag":"invalid-repeat-cap","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}