{"record":{"id":"248c3bd6c975295e","repo":"datawhalechina/hello-agents","slug":"incident-incident-id-not-found-available-li","errorCode":null,"errorMessage":"Incident '{incident_id}' not found. Available: {list_incidents()}","messagePattern":"Incident '(.+?)' not found\\. Available: (.+?)","errorType":"http","errorClass":"FileNotFoundError","httpStatus":404,"severity":"error","filePath":"Co-creation-projects/zjzhou-SREOnCallAgent/src/agents/pipeline.py","lineNumber":26,"sourceCode":"\nfrom src.core.llm_client import HelloAgentsLLM\nfrom src.agents.triage_agent import TriageAgent\nfrom src.agents.investigation_agent import InvestigationAgent\nfrom src.agents.postmortem_agent import PostmortemAgent\n\nDATA_DIR = Path(__file__).resolve().parents[2] / \"data\"\nINCIDENTS_DIR = DATA_DIR / \"incidents\"\nRUNBOOKS_DIR = DATA_DIR / \"runbooks\"\n\n\ndef list_incidents():\n    return [p.stem for p in INCIDENTS_DIR.glob(\"*.json\")]\n\n\ndef load_incident(incident_id: str) -> Dict[str, Any]:\n    path = INCIDENTS_DIR / f\"{incident_id}.json\"\n    if not path.exists():\n        raise FileNotFoundError(\n            f\"Incident '{incident_id}' not found. \"\n            f\"Available: {list_incidents()}\"\n        )\n    with open(path) as f:\n        return json.load(f)\n\n\ndef run_pipeline(incident_id: str, verbose: bool = True) -> Dict[str, Any]:\n    \"\"\"\n    Full three-stage SRE pipeline for a given incident ID.\n\n    Returns a dict with: incident_id, plan, findings, report\n    \"\"\"\n    incident = load_incident(incident_id)\n    llm = HelloAgentsLLM(verbose=verbose)\n\n    # Stage 1: Triage — Plan-and-Solve\n    triage = TriageAgent(llm)","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/zjzhou-SREOnCallAgent/src/agents/pipeline.py#L8-L44","documentation":"Raised by load_incident in src/agents/pipeline.py when data/incidents/{incident_id}.json does not exist. The message includes list_incidents() — the stems of every JSON file in data/incidents/ — so it doubles as a directory listing. Note path.exists() follows the literal string; any ID not matching a filename exactly (case, extension, traversal) fails.","triggerScenarios":"Calling run_pipeline('INC-001') when the file is data/incidents/inc-001.json; passing an ID with '.json' appended (produces 'x.json.json'); requesting an incident never created; path traversal like '../secrets' finds nothing and errors the same way.","commonSituations":"Case-mismatch between API input and filenames; users typing IDs from memory instead of listing available ones; the data directory not cloned/deployed with the repo; ID format changed (INC-42 vs 42) between dataset versions.","solutions":["Read the 'Available:' list in the error message and use one of those exact IDs.","If the incident should exist, check data/incidents/ for the exact filename (case, no .json suffix in the ID).","Regenerate or restore the incident JSON if the data directory is incomplete.","When exposing via API, list incidents through the provided list endpoint instead of guessing IDs."],"exampleFix":"# before\nresult = run_pipeline(\"INC-999\")\n\n# after\nfrom src.agents.pipeline import list_incidents\nprint(list_incidents())  # ['inc-001', 'inc-002']\nresult = run_pipeline(\"inc-001\")","handlingStrategy":"validation","validationCode":"from src.agents.pipeline import list_incidents\n\nAVAILABLE = set(list_incidents())\nif incident_id not in AVAILABLE:\n    raise ValueError(f\"unknown incident {incident_id!r}; choose from {sorted(AVAILABLE)}\")\nresult = run_pipeline(incident_id)","typeGuard":"import re\n\ndef is_valid_incident_id(v: str) -> bool:\n    \"\"\"Alphanumeric/dash IDs only, no extension, no traversal.\"\"\"\n    return bool(re.fullmatch(r\"[A-Za-z0-9_-]+\", v))","tryCatchPattern":"try:\n    result = run_pipeline(incident_id)\nexcept FileNotFoundError as e:\n    print(e)  # message lists available incidents\n    incident_id = list_incidents()[0]\n    result = run_pipeline(incident_id)","preventionTips":["Always resolve IDs via list_incidents() first instead of hardcoding.","Normalize casing and strip '.json' from user-supplied IDs before use.","Ship data/incidents/*.json with the deployment; verify presence in a health check.","Reject path-like IDs at the API boundary (regex allow-list) to avoid traversal probing."],"tags":["python","file-not-found","data","sre"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}