HKUDS/Vibe-Trading · error · HTTPException

too many running benches; wait for one to finish

Error message

too many running benches; wait for one to finish

What it means

After int coercion, limit must lie in 1..MAX_RESULT_ROWS inclusive. Zero, negatives, and values above the cap raise this ValueError, bounding result-set size and page size against the read-only snapshot.

Source

Thrown at agent/src/api/alpha_routes.py:517

        """Queue a background bench job and return a job_id."""
        # Cheap period parse pre-check so we 400 here instead of letting the
        # worker fail asynchronously.
        from src.tools.alpha_bench_tool import _parse_period

        try:
            _parse_period(payload.period)
        except ValueError as exc:
            raise HTTPException(status_code=400, detail=f"invalid period: {exc}")

        # Concurrency cap. We peek at the semaphore counter rather than
        # ``acquire(block=False)`` so the actual acquire happens inside the
        # worker (after the 202 is returned). _value is a CPython
        # implementation detail but it's been stable since 3.0 and asyncio's
        # own ``locked()`` uses it.
        sem = _get_bench_semaphore()
        # ``locked()`` returns True iff the counter is 0; defensive check.
        if sem.locked() or getattr(sem, "_value", MAX_CONCURRENT_BENCHES) <= 0:
            raise HTTPException(
                status_code=429,
                detail="too many running benches; wait for one to finish",
            )

        _prune_old_jobs()

        job_id = uuid.uuid4().hex
        with _JOBS_LOCK:
            ALPHA_BENCH_JOBS[job_id] = {
                "job_id": job_id,
                "status": "queued",
                "zoo": payload.zoo,
                "universe": payload.universe,
                "period": payload.period,
                "top": payload.top,
                "created_at": _now_iso(),
                "progress": {"n_done": 0, "n_total": 0, "current_alpha_id": None},
                "result": None,

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Clamp before calling: limit=max(1, min(int(raw), MAX_RESULT_ROWS))
  2. Treat 0/unlimited as the cap: limit = MAX_RESULT_ROWS if raw in (0, None) else raw
  3. Import MAX_RESULT_ROWS from the module instead of hardcoding the cap

Example fix

# before
execute(action='universe', limit=0)  # meant 'unlimited'
# after
from agent.src.tools.taiwan_stock_data_tool import MAX_RESULT_ROWS
execute(action='universe', limit=MAX_RESULT_ROWS)
Defensive patterns

Strategy: validation

Validate before calling

from agent.src.tools.taiwan_stock_data_tool import MAX_RESULT_ROWS
limit = max(1, min(int(raw_limit), MAX_RESULT_ROWS)) if raw_limit else MAX_RESULT_ROWS

Try / catch

try:
    tool.execute(action='universe', limit=limit)
except ValueError as e:
    if 'between 1 and' in str(e):
        result = tool.execute(action='universe', limit=MAX_RESULT_ROWS)
    else:
        raise

Prevention

When it happens

Trigger: Calling execute(..., limit=0), limit=-1, or limit=100000 exceeding MAX_RESULT_ROWS. Note limit=0 is a common 'no limit' convention elsewhere but is rejected here — the minimum is 1.

Common situations: API gateway defaulting limit=0 to mean unlimited; pagination math producing 0 on the last empty page; user-supplied page size of 9999 from a UI dropdown; copying limits tuned for another tool with a different cap.

Related errors


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