abi/screenshot-to-code · warning · HTTPException
Run has no captured output
Error message
Run has no captured output
What it means
Raised by GET /agent-runs/{run_id}/output (404) when the run exists in the index but its directory contains neither final_selfcontained.html nor final.html. The route serves captured artifacts, so it 404s when generation never finished far enough to write an output file, or the files were deleted from disk even though the DB row remains.
Source
Thrown at backend/routes/agent_runs.py:211
except json.JSONDecodeError:
# A crashed writer can leave a torn final line.
continue
if not include_stream_deltas and event.get("type") == "stream_delta":
continue
events.append(event)
return AgentRunDetailResponse(run=run, events=events)
@router.get("/agent-runs/{run_id}/output")
async def get_agent_run_output(run_id: str) -> HTMLResponse:
_fetch_run(run_id)
run_dir = os.path.join(get_agent_runs_directory(), run_id)
for candidate in ("final_selfcontained.html", "final.html"):
path = os.path.join(run_dir, candidate)
if os.path.isfile(path):
with open(path, "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
raise HTTPException(status_code=404, detail="Run has no captured output")
@router.get("/agent-runs/{run_id}/assets/{filename}")
async def get_agent_run_asset(run_id: str, filename: str) -> FileResponse:
_fetch_run(run_id)
assets_dir = os.path.join(get_agent_runs_directory(), run_id, "assets")
# basename() strips any traversal components before the containment check.
safe_name = os.path.basename(filename)
path = os.path.realpath(os.path.join(assets_dir, safe_name))
if not path.startswith(os.path.realpath(assets_dir) + os.sep):
raise HTTPException(status_code=400, detail="Invalid asset path")
if not os.path.isfile(path):
raise HTTPException(status_code=404, detail="Asset not found")
return FileResponse(path)
@router.post("/agent-runs/prune", response_model=PruneAgentRunsResponse)
async def prune_agent_runs(request: PruneAgentRunsRequest) -> PruneAgentRunsResponse:View on GitHub (pinned to d026163f58)
Solutions
- Check the run's status via GET /agent-runs/{run_id} and retry once it is complete.
- List the run directory under the runs_directory returned by GET /agent-runs and confirm final.html / final_selfcontained.html exist.
- If files were deleted, prune the run (POST /agent-runs/prune) so the stale DB row is removed.
- If generation failed, re-run the generation that produces the output.
Example fix
# before
resp = client.get(f"/agent-runs/{run_id}/output") # 404 'Run has no captured output'
# after
detail = client.get(f"/agent-runs/{run_id}").json()
if detail["run"]["status"] != "completed":
wait_for_completion(run_id)
resp = client.get(f"/agent-runs/{run_id}/output") Defensive patterns
Strategy: validation
Validate before calling
detail = client.get(f"/agent-runs/{run_id}").json()
status = detail["run"]["status"]
if status != "completed":
raise RuntimeError(f"run not finished (status={status}); no output yet") Type guard
def run_has_output(detail: dict) -> bool:
"""Heuristic: only completed runs capture final HTML output."""
return detail["run"].get("status") == "completed" Try / catch
try:
resp = client.get(f"/agent-runs/{run_id}/output")
resp.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 404 and "captured output" in e.response.text:
resp = None # still running or artifacts missing
else:
raise Prevention
- Poll run status until completion before fetching /output.
- Treat a missing output file as 'not done yet or failed', and re-check status.
- Prune runs whose directories were half-deleted so stale rows disappear.
When it happens
Trigger: Calling /agent-runs/{run_id}/output for a run that is still in progress, failed mid-generation, or whose run directory was partially cleaned (DB row kept, HTML files removed).
Common situations: Polling the output URL while the agent is still running; a crashed/killed generation; disk cleanup that removed run directories but not the SQLite index; checking output of a run that only produced assets.
Related errors
- Run not found
- No runs recorded
- Asset not found
- Eval set not found: {set_name}
- Eval set not found: {request.eval_set}
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/a8f9c3e2f820793c.
Report an issue: GitHub.