{"record":{"id":"3e6ce876f8445ccd","repo":"abi/screenshot-to-code","slug":"run-not-found","errorCode":null,"errorMessage":"Run not found","messagePattern":"Run not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/routes/agent_runs.py","lineNumber":149,"sourceCode":"                continue\n    return total\n\n\ndef _fetch_run(run_id: str) -> AgentRunSummary:\n    if not RUN_ID_PATTERN.match(run_id):\n        raise HTTPException(status_code=400, detail=\"Invalid run id\")\n    if not os.path.isfile(get_agent_runs_db_path()):\n        raise HTTPException(status_code=404, detail=\"No runs recorded\")\n    conn = open_index_db()\n    try:\n        row = conn.execute(\n            f\"SELECT {', '.join(_RUN_COLUMNS)} FROM runs WHERE run_id = ?\",\n            (run_id,),\n        ).fetchone()\n    finally:\n        conn.close()\n    if row is None:\n        raise HTTPException(status_code=404, detail=\"Run not found\")\n    return _row_to_summary(row)\n\n\n@router.get(\"/agent-runs\", response_model=AgentRunListResponse)\nasync def list_agent_runs(limit: int = 200) -> AgentRunListResponse:\n    runs_directory = get_agent_runs_directory()\n    if not os.path.isfile(get_agent_runs_db_path()):\n        return AgentRunListResponse(\n            runs=[], total_size_bytes=0, runs_directory=runs_directory\n        )\n\n    conn = open_index_db()\n    try:\n        rows = conn.execute(\n            f\"SELECT {', '.join(_RUN_COLUMNS)} FROM runs \"\n            \"ORDER BY created_at DESC, run_id DESC LIMIT ?\",\n            (max(1, min(limit, 1000)),),\n        ).fetchall()","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/backend/routes/agent_runs.py#L131-L167","documentation":"Raised by _fetch_run() (404) after the run id passed the format check and the index DB exists, but the SELECT on the runs table returned no row. The id is well-formed but unknown: either the run never existed, was pruned via POST /agent-runs/prune, or its directory/DB entry was removed manually.","triggerScenarios":"GET /agent-runs/{run_id}, /output, or /assets/{filename} with a syntactically valid id that is not in the runs table — e.g. an id from an old session after a prune, or a typo that still matches the pattern (wrong hex suffix).","commonSituations":"Stale id stored in a frontend/bookmark after prune ran; the DB was rebuilt from scratch losing old entries; concurrent deletion between list and detail fetch.","solutions":["Re-list runs with GET /agent-runs and use an id from the current response.","If the run should still exist, check whether POST /agent-runs/prune deleted it (it returns deleted_run_ids).","Inspect the runs table (sqlite3 on the DB path from GET /agent-runs) to confirm which ids are actually recorded.","Make sure you are hitting the same backend instance/data directory that recorded the run."],"exampleFix":"# before\nresp = client.get(f\"/agent-runs/{run_id}/output\")  # 404 'Run not found'\n\n# after\nruns = {r[\"run_id\"] for r in client.get(\"/agent-runs\").json()[\"runs\"]}\nif run_id not in runs:\n    run_id = sorted(runs)[-1]  # fall back to newest run\nresp = client.get(f\"/agent-runs/{run_id}/output\")","handlingStrategy":"validation","validationCode":"known = {r[\"run_id\"] for r in client.get(\"/agent-runs\").json()[\"runs\"]}\nif run_id not in known:\n    raise LookupError(f\"run not in index: {run_id}; known={sorted(known)[:5]}\")","typeGuard":"def run_exists(run_id: str, listing: dict) -> bool:\n    return any(r[\"run_id\"] == run_id for r in listing[\"runs\"])","tryCatchPattern":"try:\n    detail = client.get(f\"/agent-runs/{run_id}\").raise_for_status().json()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404 and \"Run not found\" in e.response.text:\n        detail = newest(client.get(\"/agent-runs\").json()[\"runs\"])  # or drop the id\n    else:\n        raise","preventionTips":["Treat ids from GET /agent-runs as the source of truth and re-list after prunes.","Discard stored ids on 404 instead of retrying them.","Watch prune responses (deleted_run_ids) to invalidate caches."],"tags":["fastapi","http-404","sqlite","agent-runs","lifecycle"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}