{"record":{"id":"187331d79783230c","repo":"unclecode/crawl4ai","slug":"artifact-not-found-187331","errorCode":null,"errorMessage":"Artifact not found","messagePattern":"Artifact not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"deploy/docker/server.py","lineNumber":657,"sourceCode":"        raise HTTPException(413, \"Artifact too large\")\n    except QuotaExceeded:\n        raise HTTPException(507, \"Artifact storage quota exceeded\")\n    return {\n        \"artifact_id\": meta[\"artifact_id\"],\n        \"url\": f\"/artifacts/{meta['artifact_id']}\",\n        \"mime\": meta[\"mime\"],\n        \"size\": meta[\"size\"],\n    }\n\n\n@app.get(\"/artifacts/{artifact_id}\")\nasync def get_artifact(artifact_id: str, _td: Dict = Depends(token_dep)):\n    \"\"\"Fetch a previously generated artifact by its opaque id (authed).\"\"\"\n    from artifacts import resolve_artifact, ArtifactNotFound\n    try:\n        path, mime = resolve_artifact(artifact_id)\n    except ArtifactNotFound:\n        raise HTTPException(404, \"Artifact not found\")\n    return FileResponse(path, media_type=mime, headers={\"X-Content-Type-Options\": \"nosniff\"})\n\n\n# Screenshot endpoint\n\n\n@app.post(\"/screenshot\")\n@limiter.limit(config[\"rate_limiting\"][\"default_limit\"])\n@mcp_tool(\"screenshot\")\nasync def generate_screenshot(\n    request: Request,\n    body: ScreenshotRequest,\n    _td: Dict = Depends(token_dep),\n):\n    \"\"\"\n    Capture a full-page PNG screenshot of the specified URL, waiting an optional delay before capture.\n    Use when you need an image snapshot of the rendered page. The image is also written to the\n    sandboxed artifact store; the response includes an `artifact_id` and a `url` to fetch it.","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/server.py#L639-L675","documentation":"A 404 from GET /artifacts/{artifact_id}: resolve_artifact() raised ArtifactNotFound — no artifact with that id exists in the sandboxed store. Ids are opaque, so any typo, expired/evicted artifact, or wrong server yields this.","triggerScenarios":"GET /artifacts/<id> where the id was mistyped, the artifact was deleted/pruned after quota pressure, the service restarted with a non-persistent store volume, or the request hit a different container instance than the one that wrote it.","commonSituations":"Multi-replica deployments without shared artifact storage; artifacts stored in container-local tmpfs lost on restart; copy-paste truncation of long ids; retention jobs pruning old artifacts.","solutions":["Verify the artifact_id against the one returned in the original response body (fields artifact_id / url).","If artifacts are needed later, back the store with a persistent volume or shared storage across replicas.","Re-generate the artifact by re-running the /screenshot or /pdf call.","Treat 404 as terminal in clients — regenerate rather than retry the fetch."],"exampleFix":"# client\nresp = requests.get(f'{base}/artifacts/{art[\"artifact_id\"]}')\nif resp.status_code == 404:\n    art = requests.post(f'{base}/pdf', json={'url': url}, headers=auth).json()  # regenerate","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp = requests.get(f'{BASE}/artifacts/{art_id}', headers=hdrs)\nif resp.status_code == 404:\n    # regenerate instead of retrying the fetch\n    art = requests.post(f'{BASE}/screenshot', json={'url': url}, headers=hdrs).json()\n    art_id = art['artifact_id']\n    resp = requests.get(f'{BASE}/artifacts/{art_id}', headers=hdrs)","preventionTips":["Persist the artifact bytes you care about; don't rely on server-side retention.","Back the store with a persistent volume if artifacts must survive restarts.","Treat 404 as permanent — regenerate rather than retry."],"tags":["artifacts","http-404","storage"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}