ATH-MaaS/Pixelle-Video · warning · HTTPException

Task {task_id} not found

Error message

Task {task_id} not found

What it means

A 404 HTTPException raised by the GET /tasks/{task_id} endpoint in api/routers/tasks.py when task_manager.get_task(task_id) returns None/falsy. It is the API's explicit signal that no task exists with the supplied ID. This is an expected, controlled response, not an internal failure.

Source

Thrown at api/routers/tasks.py:67

        raise HTTPException(status_code=500, detail=str(e))


@router.get("/{task_id}", response_model=Task)
async def get_task(task_id: str):
    """
    Get task details
    
    Retrieve detailed information about a specific task.
    
    - **task_id**: Task ID
    
    Returns task details including status, progress, and result (if completed).
    """
    try:
        task = task_manager.get_task(task_id)
        
        if not task:
            raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
        
        return task
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Get task error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/{task_id}")
async def cancel_task(task_id: str):
    """
    Cancel task
    
    Cancel a running or pending task.
    
    - **task_id**: Task ID

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Verify the task_id used in the request matches the ID returned by the task-creation endpoint exactly (no truncation, no whitespace).
  2. Re-create the task if the server was restarted and it used an in-memory task manager; persist task IDs externally if tasks must survive restarts.
  3. Confirm you are polling the same server instance that accepted the task (check sticky sessions or shared task store).
  4. Check whether the task was cancelled/completed and cleaned up by retention logic before polling.
  5. Handle HTTP 404 in the client by treating the task as unknown and stopping polling instead of retrying forever.

Example fix

// before: poll blindly
const res = await fetch(`/tasks/${taskId}`);
const task = await res.json();
// after: check status first
const res = await fetch(`/tasks/${taskId}`);
if (res.status === 404) {
  throw new Error(`Task ${taskId} no longer exists; re-submit the job`);
}
const task = await res.json();
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side pre-check
if (!taskId || !/^[0-9a-fA-F-]{8,64}$/.test(taskId.trim())) {
  throw new Error('Refusing to poll: task_id missing or malformed');
}

Type guard

function isTaskResponse(x) {
  return x != null && typeof x === 'object' && 'task_id' in x && 'status' in x;
}

Try / catch

try {
  const res = await fetch(`/tasks/${taskId}`);
  if (res.status === 404) {
    // task gone / server restarted: stop polling, re-submit if needed
    return null;
  }
  if (!res.ok) throw new Error(`Unexpected ${res.status}`);
  return await res.json();
} catch (err) {
  handlePollFailure(err);
}

Prevention

When it happens

Trigger: Calling GET /{task_id} with a task_id that was never created, a typo'd or truncated UUID, or a task whose record was purged from the manager's store (e.g. in-memory TaskManager restarted, or task evicted after retention/cleanup).

Common situations: Client stores the task ID from a 202-style submit response but the server restarted (in-memory task registry lost); polling a task after it aged out of retention; hardcoding example IDs from docs; load balancer routing the poll to a different backend instance than the one that owns the task.

Related errors


AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30). Data as JSON: /api/errors/092c9d94b9b99989. Report an issue: GitHub.