harry0703/MoneyPrinterTurbo · warning · HttpException

{request_id}: {str(e)}

Error message

{request_id}: {str(e)}

What it means

Raised in create_video (app/controllers/v1/video.py) when task_manager.add_task raises TaskQueueFullError. The handler is cleanup-aware: it deletes the just-created task record from state (so the rejected task does not linger) before returning 429 with the queue-full message. This is the HTTP-visible form of the manager's bounded-queue backpressure described in error 1.

Source

Thrown at app/controllers/v1/video.py:217

):
    task_id = utils.get_uuid()
    request_id = base.get_task_id(request)
    try:
        task = {
            "task_id": task_id,
            "request_id": request_id,
            "params": body.model_dump(),
        }
        sm.state.update_task(task_id)
        task_manager.add_task(tm.start, task_id=task_id, params=body, stop_at=stop_at)
        logger.success(f"Task created: {utils.to_json(task)}")
        return utils.get_response(200, task)
    except TaskQueueFullError as e:
        sm.state.delete_task(task_id)
        logger.warning(
            f"reject task because queue is full, request_id: {request_id}, task_id: {task_id}"
        )
        raise HttpException(
            task_id=task_id, status_code=429, message=f"{request_id}: {str(e)}"
        )
    except ValueError as e:
        raise HttpException(
            task_id=task_id, status_code=400, message=f"{request_id}: {str(e)}"
        )

@router.get("/tasks", response_model=TaskListResponse, summary="Get all tasks")
def get_all_tasks(
    request: Request,
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1),
):
    tasks, total = sm.state.get_all_tasks(page, page_size)

    response = {
        "tasks": [_public_task_data(task) for task in tasks],
        "total": total,

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Retry the POST with exponential backoff + jitter; the task was not created, so a plain resubmission is safe (no duplicate-task cleanup needed).
  2. Check GET /api/v1/tasks for stuck running tasks and delete them to free capacity.
  3. Raise max_concurrent_tasks / max_queued_tasks in the video controller's InMemoryTaskManager settings if the load is legitimate.
  4. Throttle submitters client-side to smooth bursts.

Example fix

# before
resp = requests.post(f"{base}/api/v1/videos", json=body, headers=h)
resp.raise_for_status()

# after
import time, random
for attempt in range(6):
    resp = requests.post(f"{base}/api/v1/videos", json=body, headers=h)
    if resp.status_code != 429:
        break
    time.sleep(min(60, (2 ** attempt) + random.random()))
resp.raise_for_status()
Defensive patterns

Strategy: retry

Validate before calling

# probe queue pressure before a burst
resp = requests.get(f"{base}/api/v1/tasks?page=1&page_size=1", headers=h)
# if your deployment reports many active tasks, delay the burst

Type guard

def is_retryable_queue_reject(resp) -> bool:
    return resp.status_code == 429 and "queue is full" in resp.text

Try / catch

for attempt in range(6):
    try:
        resp = post_video_task(body)
        break
    except TaskQueueRejected:  # 429 mapped in your client SDK
        time.sleep(min(60, 2 ** attempt + random.random()))
else:
    raise RuntimeError("video queue saturated; try later")

Prevention

When it happens

Trigger: POST /api/v1/videos while all workers are busy and the queue is at max_queued_tasks; burst creation of video tasks from a script; upstream generation API slowness causing queue saturation.

Common situations: Batch generation scripts without retry/backoff; concurrency budget sized below real traffic; stuck tasks pinning workers so the queue never drains.

Related errors


AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14). Data as JSON: /api/errors/3d08fd09ca8adea8. Report an issue: GitHub.