HKUDS/Vibe-Trading · error · ValueError
retry_max_delay_ms must be at least retry_base_delay_ms
Error message
retry_max_delay_ms must be at least retry_base_delay_ms
What it means
The executor enforces retry_max_delay_ms >= retry_base_delay_ms so the backoff cap cannot be below its starting delay — otherwise the exponential sequence would be nonsensical (capped below its first term). Both parameters may also come from tuning defaults, so the check compares the resolved values.
Source
Thrown at agent/src/scheduled_research/executor.py:271
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:
return
self._stopping = FalseView on GitHub (pinned to 80ffdda44c)
Solutions
- Raise retry_max_delay_ms to at least retry_base_delay_ms (typically much larger, e.g. base 1s, max 300s).
- When overriding base delay in config, override the max delay in the same place.
- Use the defaults unless you specifically need custom backoff.
Example fix
# before SchedulerExecutor(retry_base_delay_ms=60000, retry_max_delay_ms=5000) # after SchedulerExecutor(retry_base_delay_ms=1000, retry_max_delay_ms=300000)
Defensive patterns
Strategy: validation
Validate before calling
retry_base_delay_ms = max(0, int(retry_base_delay_ms))
retry_max_delay_ms = max(retry_base_delay_ms, int(retry_max_delay_ms))
executor = SchedulerExecutor(retry_base_delay_ms=retry_base_delay_ms,
retry_max_delay_ms=retry_max_delay_ms) Prevention
- Override base and max delay together in config.
- Leave both at defaults unless custom backoff is required.
When it happens
Trigger: Constructing with retry_base_delay_ms=60000 and retry_max_delay_ms=5000, or where an explicit base delay overrides a smaller default max delay while the max stays at its tuning default.
Common situations: Setting only one of the two knobs in config: e.g. raising base delay to 60s while the max stays at a 30s default, breaking the invariant.
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
- max_consecutive_failures must be at least 1
- retry_base_delay_ms must be non-negative
- cron schedule has no matching time within search window: {sc
- cron field {part!r} is out of range; expected {low}-{high}
- cron field {part!r} is not valid; each field must be *, */n,
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/9589cb1efdf7fd18.
Report an issue: GitHub.