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 IDView on GitHub (pinned to 848b054e4f)
Solutions
- Verify the task_id used in the request matches the ID returned by the task-creation endpoint exactly (no truncation, no whitespace).
- 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.
- Confirm you are polling the same server instance that accepted the task (check sticky sessions or shared task store).
- Check whether the task was cancelled/completed and cleaned up by retention logic before polling.
- 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
- Persist the task ID returned at creation; never hardcode or hand-type IDs.
- Stop polling after a 404 instead of retrying indefinitely.
- Back task storage with a shared/persistent store so restarts don't orphan task IDs.
- Trim/validate the ID before sending; watch for copy-paste whitespace.
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.