{"record":{"id":"c5cfbba84ae4fc5a","repo":"OpenBMB/ChatDev","slug":"artifact-stream-not-available","errorCode":null,"errorMessage":"Artifact stream not available","messagePattern":"Artifact stream not available","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"server/routes/artifacts.py","lineNumber":31,"sourceCode":"MAX_FILE_SIZE = 20 * 1024 * 1024  # 20 MB\n\n\ndef _split_csv(value: Optional[str]) -> Optional[List[str]]:\n    if not value:\n        return None\n    parts = [part.strip() for part in value.split(\",\")]\n    filtered = [part for part in parts if part]\n    return filtered or None\n\n\ndef _get_session_and_queue(session_id: str):\n    manager = get_websocket_manager()\n    session = manager.session_store.get_session(session_id)\n    if not session:\n        raise HTTPException(status_code=404, detail=\"Session not found\")\n    queue = session.artifact_queue\n    if queue is None:\n        raise HTTPException(status_code=404, detail=\"Artifact stream not available\")\n    return manager, queue\n\n\n@router.get(\"/api/sessions/{session_id}/artifact-events\")\nasync def poll_artifact_events(\n    session_id: str,\n    wait_seconds: float = Query(25.0, ge=0.0, le=60.0),\n    after: Optional[int] = Query(None, ge=0),\n    include_mime: Optional[str] = Query(None),\n    include_ext: Optional[str] = Query(None),\n    max_size: Optional[int] = Query(None, gt=0),\n    limit: int = Query(25, ge=1, le=100),\n):\n    manager, queue = _get_session_and_queue(session_id)\n    include_mime_list = _split_csv(include_mime)\n    include_ext_list = _split_csv(include_ext)\n\n    events, next_cursor, timed_out = await asyncio.to_thread(","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/server/routes/artifacts.py#L13-L49","documentation":"The session exists but session.artifact_queue is None, meaning no artifact event stream was ever attached to it. The helper returns 404 because there is nothing to poll or stream from this session.","triggerScenarios":"Calling artifact endpoints on a session whose websocket connection never initialized the artifact queue, or after the queue was torn down at session close.","commonSituations":"Polling artifact events on a session that completed without ever connecting a websocket client, or after the session's streaming lifecycle ended.","solutions":["Establish the websocket connection for the session first so the artifact queue is created","Run a workflow that produces artifacts before polling","Reconnect the session if the queue was torn down after disconnect","Confirm you're using the same server instance that owns the session"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# only poll after the session reports a websocket connection / artifacts exist\nif not session_has_artifacts(session_id):\n    return  # skip polling","typeGuard":null,"tryCatchPattern":"if resp.status_code == 404 and resp.json()['detail'] == 'Artifact stream not available':\n    connect_websocket(session_id)  # initialize the queue, then retry","preventionTips":["Open the session websocket before polling artifact events","Don't poll sessions whose runs never produced artifacts"],"tags":["http-404","artifacts","websocket","session"],"backgroundTag":"resource-unavailable","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}