assafelovic/gpt-researcher · error · ValueError
rate_limit_delay must be a number, got {rate_limit_delay!r}
Error message
rate_limit_delay must be a number, got {rate_limit_delay!r} What it means
RateLimiter.configure raises ValueError when rate_limit_delay cannot be converted to a float — i.e. it's not None, not a number, and not a numeric string. This typically means a misconfigured RATE_LIMIT_DELAY env var or config value containing non-numeric text.
Source
Thrown at gpt_researcher/utils/rate_limiter.py:65
if cls._lock is None:
cls._lock = asyncio.Lock()
return cls._lock
def configure(self, rate_limit_delay: float):
"""
Configure the global rate limit delay.
Args:
rate_limit_delay: Minimum seconds between requests (0 = no limit)
"""
# Env/config may hand us strings; wait_if_needed compares as float.
if rate_limit_delay is None:
self.rate_limit_delay = 0.0
return
try:
delay = float(rate_limit_delay)
except (TypeError, ValueError) as e:
raise ValueError(
f"rate_limit_delay must be a number, got {rate_limit_delay!r}"
) from e
if delay < 0:
raise ValueError(f"rate_limit_delay must be non-negative, got {delay}")
self.rate_limit_delay = delay
async def wait_if_needed(self):
"""
Wait if needed to enforce global rate limiting.
This method ensures that regardless of how many WorkerPools are active,
the SCRAPER_RATE_LIMIT_DELAY is respected globally.
"""
if self.rate_limit_delay <= 0:
return # No rate limiting
lock = self.get_lock()
async with lock:View on GitHub (pinned to 6f998577d5)
Solutions
- Set rate_limit_delay to a plain number or numeric string, e.g. '1.5' (seconds)
- Fix the env var: export RATE_LIMIT_DELAY=1.5 — no units, no commas
- Pass None (or omit) if you want no delay; it coerces to 0.0
- Add a startup check: float(os.getenv('RATE_LIMIT_DELAY', '0')) to fail fast with a clear message
Example fix
# before os.environ['RATE_LIMIT_DELAY'] = '0.5s' limiter = RateLimiter(0.5) # ValueError: rate_limit_delay must be a number, got '0.5s' # after os.environ['RATE_LIMIT_DELAY'] = '0.5' limiter = RateLimiter(0.5)
Defensive patterns
Strategy: validation
Validate before calling
import os
raw = os.getenv('RATE_LIMIT_DELAY', '0')
delay = float(raw) # raises here with a clear traceback if misconfigured Type guard
def valid_delay(v) -> bool:
if v is None:
return True
try:
return float(v) >= 0
except (TypeError, ValueError):
return False Try / catch
try:
limiter = RateLimiter(raw_delay)
except ValueError as e:
logger.warning('Bad RATE_LIMIT_DELAY %r, defaulting to 0', raw_delay)
limiter = RateLimiter(0) Prevention
- Document RATE_LIMIT_DELAY as a bare number of seconds (no units, no commas)
- Validate numeric env vars once at startup, not deep in library code
- Use 0 or unset rather than creative sentinel values for 'disabled'
When it happens
Trigger: Setting rate_limit_delay to a non-numeric string like '0.5s', 'half', '1,5' (comma decimal), or passing an object with no __float__; the value reaches configure() via RateLimiter __init__ from config parsing.
Common situations: RATE_LIMIT_DELAY env var with units ('2/sec'), localized decimal commas, quotes/whitespace artifacts, or a config file value accidentally set to a boolean/list.
Related errors
- max_tokens={max_tokens} exceeds the largest output limit of
- rate_limit_delay must be non-negative, got {delay}
- Invalid retriever(s) found: {', '.join(invalid_retrievers)}.
- Invalid reasoning effort: {reasoning_effort_str}. Valid opti
- RETRIEVER_ENDPOINT environment variable not set
AI-assisted analysis of assafelovic/gpt-researcher@6f998577d5 (2026-08-28).
Data as JSON: /api/errors/a57efadd19ae0c28.
Report an issue: GitHub.