{"record":{"id":"ac40ad7056c41949","repo":"HKUDS/Vibe-Trading","slug":"max-consecutive-failures-must-be-at-least-1","errorCode":null,"errorMessage":"max_consecutive_failures must be at least 1","messagePattern":"max_consecutive_failures must be at least 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/scheduled_research/executor.py","lineNumber":267,"sourceCode":"        self._now_fn = now_fn\n        self._enabled = enabled\n        self._max_consecutive_failures = (\n            max_consecutive_failures\n            if max_consecutive_failures is not None\n            else tuning.vibe_trading_scheduler_max_consecutive_failures\n        )\n        self._retry_base_delay_ms = (\n            retry_base_delay_ms\n            if retry_base_delay_ms is not None\n            else tuning.vibe_trading_scheduler_retry_base_delay_ms\n        )\n        self._retry_max_delay_ms = (\n            retry_max_delay_ms\n            if retry_max_delay_ms is not None\n            else tuning.vibe_trading_scheduler_retry_max_delay_ms\n        )\n        if self._max_consecutive_failures < 1:\n            raise ValueError(\"max_consecutive_failures must be at least 1\")\n        if self._retry_base_delay_ms < 0:\n            raise ValueError(\"retry_base_delay_ms must be non-negative\")\n        if self._retry_max_delay_ms < self._retry_base_delay_ms:\n            raise ValueError(\"retry_max_delay_ms must be at least retry_base_delay_ms\")\n        self._task: asyncio.Task | None = None\n        self._wakeup: asyncio.Event | None = None\n        self._stopping = False\n        self._recovered_stale_running = False\n\n    @property\n    def is_running(self) -> bool:\n        \"\"\"Return whether the background loop task is active.\"\"\"\n        return self._task is not None and not self._task.done()\n\n    def start(self) -> None:\n        \"\"\"Start the background loop.\n\n        Idempotent. When disabled, this is a no-op.","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/scheduled_research/executor.py#L249-L285","documentation":"The scheduled-research executor validates its retry configuration in __init__ and requires max_consecutive_failures >= 1. A value of 0 would mean 'disable the circuit breaker', which the executor does not support as a configured mode — it wants at least one allowed failure before halting a job.","triggerScenarios":"Constructing the executor with max_consecutive_failures=0 or a negative value, often read from a settings object or environment-driven tuning config.","commonSituations":"Operators trying to 'never pause the job' by setting the failure budget to zero, or config files where the field defaults to 0 when unset.","solutions":["Set max_consecutive_failures to 1 or higher (e.g. 5).","If the intent is 'always retry', use a large value instead of 0.","Check the tuning/settings source feeding the executor for an unset field defaulting to 0."],"exampleFix":"# before\nexecutor = SchedulerExecutor(max_consecutive_failures=0)\n# after\nexecutor = SchedulerExecutor(max_consecutive_failures=5)","handlingStrategy":"validation","validationCode":"max_consecutive_failures = max(1, int(max_consecutive_failures))\nexecutor = SchedulerExecutor(max_consecutive_failures=max_consecutive_failures)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never set the failure budget to 0; use a large value for 'always retry'.","Validate tuning config at app startup."],"tags":["python","scheduler","config-validation","retry"],"backgroundTag":"invalid-configuration-value","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}