{"record":{"id":"2dafce43c79f518c","repo":"OpenBMB/ChatDev","slug":"artifact-not-found","errorCode":null,"errorMessage":"Artifact not found","messagePattern":"Artifact not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"server/routes/artifacts.py","lineNumber":79,"sourceCode":"        \"next_cursor\": next_cursor,\n        \"timed_out\": timed_out,\n        \"has_more\": queue.last_sequence > (next_cursor or 0),\n    }\n    return payload\n\n\n@router.get(\"/api/sessions/{session_id}/artifacts/{artifact_id}\")\nasync def get_artifact(\n    session_id: str,\n    artifact_id: str,\n    mode: str = Query(\"meta\", pattern=\"^(meta|stream)$\"),\n    download: bool = Query(False),\n):\n    manager, _ = _get_session_and_queue(session_id)\n    store = manager.attachment_service.get_attachment_store(session_id)\n    record = store.get(artifact_id)\n    if not record:\n        raise HTTPException(status_code=404, detail=\"Artifact not found\")\n\n    ref = record.ref\n    if mode == \"stream\":\n        local_path = ref.local_path\n        if not local_path:\n            raise HTTPException(status_code=404, detail=\"Artifact content unavailable\")\n        path = Path(local_path)\n        if not path.exists():\n            raise HTTPException(status_code=404, detail=\"Artifact file missing\")\n        media_type = ref.mime_type or \"application/octet-stream\"\n        disposition = \"attachment\" if download else \"inline\"\n        headers = {\"Content-Disposition\": f'{disposition}; filename=\"{ref.name}\"'}\n        return StreamingResponse(path.open(\"rb\"), media_type=media_type, headers=headers)\n\n    data_uri = ref.data_uri\n    if not data_uri and ref.local_path and (ref.size or 0) <= MAX_FILE_SIZE:\n        local_path = Path(ref.local_path)\n        if local_path.exists():","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/server/routes/artifacts.py#L61-L97","documentation":"get_artifact looked up artifact_id in the session's attachment store and got no record. The ID was never registered for this session or belongs to a different session's store.","triggerScenarios":"GET /api/sessions/{session_id}/artifacts/{artifact_id} where artifact_id doesn't exist in that session's attachment store (typo, stale ID from a previous run, or artifact from another session).","commonSituations":"Client persisted artifact IDs across server restarts that cleared stores; using an artifact ID from a different session; race where the artifact record isn't written yet when the client polls.","solutions":["Use the artifact ID exactly as reported in the workflow/artifact event payload","Confirm the artifact ID belongs to this session_id","Wait for the artifact-generated event before fetching","Refresh IDs after a server restart"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"artifact_ids = {e.artifact_id for e in client.poll_artifact_events(session_id)}\nif artifact_id not in artifact_ids:\n    raise LookupError(f'unknown artifact {artifact_id}')","typeGuard":null,"tryCatchPattern":"try:\n    client.get_artifact(session_id, artifact_id)\nexcept HTTPError as e:\n    if e.response.status_code == 404 and e.response.json()['detail'] == 'Artifact not found':\n        refresh_artifact_ids(session_id)","preventionTips":["Use IDs straight from artifact events, never hardcoded","Treat 404 as a signal to refresh the artifact list"],"tags":["http-404","artifacts"],"backgroundTag":"resource-not-found","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}