datawhalechina/hello-agents · warning · HTTPException
No report found for '{incident_id}'. Call POST /incidents/in
Error message
No report found for '{incident_id}'. Call POST /incidents/investigate first. What it means
FastAPI HTTPException raised by the GET /incidents/{incident_id}/report endpoint when the given incident_id is not present in the in-memory _report_store dict. This app keeps generated post-mortem reports only in a process-local dictionary populated by POST /incidents/investigate, so a lookup miss means either the investigation never ran in this process or the process restarted and lost its state.
Source
Thrown at Co-creation-projects/zjzhou-SREOnCallAgent/src/api/main.py:81
raise HTTPException(status_code=404, detail=str(e))
start = time.time()
try:
result = run_pipeline(req.incident_id, verbose=False)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Pipeline error: {e}")
elapsed = round(time.time() - start, 1)
result["elapsed_seconds"] = elapsed
_report_store[req.incident_id] = result
return result
@app.get("/incidents/{incident_id}/report")
def get_report(incident_id: str):
"""Retrieve a previously generated post-mortem report."""
if incident_id not in _report_store:
raise HTTPException(
status_code=404,
detail=f"No report found for '{incident_id}'. Call POST /incidents/investigate first.",
)
return {
"incident_id": incident_id,
"report": _report_store[incident_id]["report"],
}
View on GitHub (pinned to 606a07d341)
Solutions
- Run POST /incidents/investigate with the same incident_id first, then GET the report
- If the server reloaded or restarted, re-run the investigation — the store is in-memory only and does not survive restarts
- Verify the incident_id string matches exactly (whitespace/case) what you sent to POST /incidents/investigate
- For durability, back _report_store with a database or file instead of a dict
Example fix
# before
GET /incidents/inc-123/report # 404: never investigated in this process
# after
POST /incidents/investigate {"incident_id": "inc-123", ...}
GET /incidents/inc-123/report Defensive patterns
Strategy: validation
Validate before calling
import requests
h = requests.get(f'{BASE}/incidents/{iid}/report')
if h.status_code == 404:
# run investigation first, then re-fetch
requests.post(f'{BASE}/incidents/investigate', json={'incident_id': iid, ...})
report = requests.get(f'{BASE}/incidents/{iid}/report').json() Try / catch
try:
report = get_report(iid)
except HTTPException as e:
if e.status_code == 404:
investigate(iid) # then retry once
else:
raise Prevention
- Always chain POST /incidents/investigate before the report GET for a new incident_id
- Treat server restarts as invalidating all previous incident_ids (in-memory store)
- Return/store the incident_id from the investigate response instead of retyping it
When it happens
Trigger: Calling GET /incidents/{id}/report before POST /incidents/investigate for the same id; calling GET after the server process restarted (the _report_store dict is wiped); using a typo'd or different incident_id than the one returned by the investigate call.
Common situations: Dev restarts uvicorn with --reload between the two calls and loses the store; frontend polls the report endpoint before the async investigation finishes; copy-pasting an incident_id from a previous run/session.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/06bf09ccc5e8768f.
Report an issue: GitHub.