HKUDS/Vibe-Trading · error · ValueError

retry_base_delay_ms must be non-negative

Error message

retry_base_delay_ms must be non-negative

What it means

The executor's exponential-backoff retry uses retry_base_delay_ms as the initial sleep between retries, so it must be non-negative. Negative delays are meaningless as timers and would be rejected by asyncio.sleep anyway, so the constructor fails fast.

Source

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

        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.
        """
        if not self._enabled or self.is_running:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set retry_base_delay_ms to 0 (immediate first retry) or a positive millisecond value such as 1000.
  2. Translate sentinel values like -1 to None/defaults before constructing the executor.
  3. Audit the tuning object feeding the parameter.

Example fix

# before
SchedulerExecutor(retry_base_delay_ms=-1)
# after
SchedulerExecutor(retry_base_delay_ms=1000)
Defensive patterns

Strategy: validation

Validate before calling

retry_base_delay_ms = max(0, int(retry_base_delay_ms))
executor = SchedulerExecutor(retry_base_delay_ms=retry_base_delay_ms)

Prevention

When it happens

Trigger: Constructing the executor with retry_base_delay_ms=-1000 or a negative tuning value (e.g. a mis-parsed env var or a subtraction bug in config code).

Common situations: Typo'd config numbers, unit conversions producing negatives, or settings templates where -1 is used as a sentinel for 'unset' and passed through without translation.

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/6a49636508eaa2a5. Report an issue: GitHub.