{"record":{"id":"229a598a250b743a","repo":"datawhalechina/hello-agents","slug":"error-229a59","errorCode":null,"errorMessage":"任务不存在","messagePattern":"任务不存在","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"Co-creation-projects/Apricity-InnocoreAI/api/routes/tasks.py","lineNumber":111,"sourceCode":"        result = await agent_controller.execute_task(task_id)\n        \n        return {\n            \"success\": True,\n            \"task_id\": task_id,\n            \"result\": result\n        }\n        \n    except Exception as e:\n        logger.error(f\"执行任务失败: {str(e)}\")\n        raise HTTPException(status_code=500, detail=str(e))\n\n@router.get(\"/{task_id}/status\", response_model=TaskResponse)\nasync def get_task_status(task_id: str):\n    \"\"\"获取任务状态\"\"\"\n    try:\n        status = await agent_controller.get_task_status(task_id)\n        if not status:\n            raise HTTPException(status_code=404, detail=\"任务不存在\")\n        \n        return TaskResponse(**status)\n        \n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"获取任务状态失败: {str(e)}\")\n        raise HTTPException(status_code=500, detail=str(e))\n\n@router.delete(\"/{task_id}\", response_model=Dict[str, Any])\nasync def cancel_task(task_id: str):\n    \"\"\"取消任务\"\"\"\n    try:\n        success = await agent_controller.cancel_task(task_id)\n        \n        if success:\n            return {\"success\": True, \"message\": \"任务已取消\"}\n        else:","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/Apricity-InnocoreAI/api/routes/tasks.py#L93-L129","documentation":"HTTPException 404 '任务不存在' raised at api/routes/tasks.py:111 when agent_controller.get_task_status returns a falsy value for the requested task_id. It means the controller has no record of the task — the task was never submitted, was cleaned up, or lived only in memory lost on restart.","triggerScenarios":"GET /tasks/{task_id}/status with a typo'd or stale task_id; task finished and evicted from the history list; server restarted so in-memory task registry was wiped; task cancelled and removed.","commonSituations":"Client holds a task_id from a previous deployment/session; in-memory task storage without persistence; polling after the retention window expired.","solutions":["Confirm the task_id by listing tasks via GET /tasks/ and matching ids.","If the server restarted, re-submit the task — in-memory registries do not survive restarts.","Persist task records (the history store) if ids must survive restarts.","On the client, treat 404 on status polls as terminal and stop polling."],"exampleFix":"// before\nresp = await client.get(f\"/tasks/{task_id}/status\")\nresp.raise_for_status()\n// after\nresp = await client.get(f\"/tasks/{task_id}/status\")\nif resp.status_code == 404:\n    # task unknown/evicted: stop polling, optionally resubmit\n    return None\nresp.raise_for_status()","handlingStrategy":"try-catch","validationCode":"resp = await client.get(f\"/tasks/{task_id}/status\")\nif resp.status_code == 404:\n    stop_polling()  # task unknown or evicted","typeGuard":"def task_exists(resp) -> bool:\n    return resp.status_code != 404","tryCatchPattern":"try:\n    status = get_task_status(task_id)\nexcept HTTPException as e:\n    if e.status_code == 404:\n        return None  # terminal; stop polling\n    raise","preventionTips":["Treat 404 during polling as terminal, not retryable","Persist task ids you intend to survive server restarts","Re-submit rather than reuse ids across deployments"],"tags":["fastapi","http-404","task-lifecycle","in-memory-state"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}