HKUDS/Vibe-Trading · error · ValueError

max_consecutive_failures must be at least 1

Error message

max_consecutive_failures must be at least 1

What it means

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.

Source

Thrown at agent/src/scheduled_research/executor.py:267

        self._now_fn = now_fn
        self._enabled = enabled
        self._max_consecutive_failures = (
            max_consecutive_failures
            if max_consecutive_failures is not None
            else tuning.vibe_trading_scheduler_max_consecutive_failures
        )
        self._retry_base_delay_ms = (
            retry_base_delay_ms
            if retry_base_delay_ms is not None
            else tuning.vibe_trading_scheduler_retry_base_delay_ms
        )
        self._retry_max_delay_ms = (
            retry_max_delay_ms
            if retry_max_delay_ms is not None
            else tuning.vibe_trading_scheduler_retry_max_delay_ms
        )
        if self._max_consecutive_failures < 1:
            raise ValueError("max_consecutive_failures must be at least 1")
        if self._retry_base_delay_ms < 0:
            raise ValueError("retry_base_delay_ms must be non-negative")
        if self._retry_max_delay_ms < self._retry_base_delay_ms:
            raise ValueError("retry_max_delay_ms must be at least retry_base_delay_ms")
        self._task: asyncio.Task | None = None
        self._wakeup: asyncio.Event | None = None
        self._stopping = False
        self._recovered_stale_running = False

    @property
    def is_running(self) -> bool:
        """Return whether the background loop task is active."""
        return self._task is not None and not self._task.done()

    def start(self) -> None:
        """Start the background loop.

        Idempotent. When disabled, this is a no-op.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set max_consecutive_failures to 1 or higher (e.g. 5).
  2. If the intent is 'always retry', use a large value instead of 0.
  3. Check the tuning/settings source feeding the executor for an unset field defaulting to 0.

Example fix

# before
executor = SchedulerExecutor(max_consecutive_failures=0)
# after
executor = SchedulerExecutor(max_consecutive_failures=5)
Defensive patterns

Strategy: validation

Validate before calling

max_consecutive_failures = max(1, int(max_consecutive_failures))
executor = SchedulerExecutor(max_consecutive_failures=max_consecutive_failures)

Prevention

When it happens

Trigger: Constructing the executor with max_consecutive_failures=0 or a negative value, often read from a settings object or environment-driven tuning config.

Common situations: 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.

Understand the failure class

Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/ac40ad7056c41949. Report an issue: GitHub.