{"record":{"id":"a760faf9b4a14c45","repo":"datawhalechina/hello-agents","slug":"site-id-not-found-site-id","errorCode":null,"errorMessage":"site_id not found: {site_id}","messagePattern":"site_id not found: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"Co-creation-projects/monkeyhlj-NetworkHealthReportAgent/src/agents/orchestrator.py","lineNumber":29,"sourceCode":"from src.tools.data_repository import DataRepository\n\n\nclass NetworkHealthOrchestrator:\n    def __init__(self) -> None:\n        self.repo = DataRepository()\n        self.log_agent = LogAnalysisAgent()\n        self.device_agent = DeviceStatusAgent()\n        self.user_agent = UserStatusAgent()\n        self.report_agent = NetworkHealthReportAgent()\n        self.qa_agent = SiteQAAgent()\n\n    def list_sites(self) -> List[Dict]:\n        return self.repo.list_sites()\n\n    def get_site(self, site_id: str) -> Dict:\n        site = self.repo.get_site(site_id)\n        if not site:\n            raise ValueError(f\"site_id not found: {site_id}\")\n        return site\n\n    def build_report(self, site_id: str, start: date, end: date) -> Dict:\n        site = self.get_site(site_id)\n        start_str = start.strftime(\"%Y-%m-%d\")\n        end_str = end.strftime(\"%Y-%m-%d\")\n\n        logs = self.repo.list_logs(site_id=site_id)\n        inventory = self.repo.list_device_inventory(site_id=site_id)\n        status_series = self.repo.list_device_status(site_id=site_id, start_date=start_str, end_date=end_str)\n        compliance = self.repo.latest_terminal_compliance(site_id=site_id)\n\n        log_result = self.log_agent.analyze(logs)\n        device_result = self.device_agent.analyze(inventory=inventory, status_series=status_series)\n        user_result = self.user_agent.analyze(terminal_row=compliance)\n\n        return self.report_agent.synthesize(\n            site=site,","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/monkeyhlj-NetworkHealthReportAgent/src/agents/orchestrator.py#L11-L47","documentation":"Orchestrator.get_site() delegates to repo.get_site(site_id) and raises ValueError(f\"site_id not found: {site_id}\") when the repository returns nothing. It is the single source of truth for unknown-site errors in NetworkHealthReportAgent: build_report and the QA path call get_site first, so an invalid site_id surfaces here before any log/inventory/compliance queries run.","triggerScenarios":"Calling build_report(site_id=...) or ask_global_question(site_id=...) with an id that is not in the data repository; typos or case mismatch ('SITE-01' vs 'site-01'); site removed from the dataset between listing the sites and requesting a report; frontend sending an empty or default site_id.","commonSituations":"Stale dropdown in the UI after the sites data file changed; scripts hardcoding a site_id from an older dataset; id normalization differences (leading zeros, uppercase) between producer and consumer; tests using fixtures with ids absent from the test repo.","solutions":["List valid ids first: orchestrator.list_sites() and use one of the returned site_id values verbatim.","Check exact spelling/case/whitespace of the id you pass; strip and match case if the repo is case-sensitive.","If the site should exist, verify the underlying data store loaded the sites file (path/env correct, JSON parsed).","In callers, translate this ValueError into a 404 (the API layer in src/api/main.py already does this) or a user-facing message."],"exampleFix":"# before\nreport = orchestrator.build_report(site_id=\"site-9\", start=start, end=end)\n# after\nvalid_ids = {s[\"site_id\"] for s in orchestrator.list_sites()}\nif \"site-9\" not in valid_ids:\n    raise SystemExit(f\"site-9 不存在，可选: {sorted(valid_ids)}\")\nreport = orchestrator.build_report(site_id=\"site-9\", start=start, end=end)","handlingStrategy":"validation","validationCode":"valid_ids = {s[\"site_id\"] for s in orchestrator.list_sites()}\nif site_id not in valid_ids:\n    raise ValueError(f\"unknown site_id {site_id!r}; valid: {sorted(valid_ids)}\")\nsite = orchestrator.get_site(site_id)","typeGuard":"def is_known_site(site_id: str) -> bool:\n    return any(s[\"site_id\"] == site_id for s in orchestrator.list_sites())","tryCatchPattern":"try:\n    site = orchestrator.get_site(site_id)\nexcept ValueError as e:\n    # unknown id is a caller error — surface it, do not retry\n    raise KeyError(str(e)) from e","preventionTips":["Always source site ids from list_sites(), never hardcode","Normalize ids (strip/case-fold) at the boundary if inputs are user-typed","Translate ValueError to HTTP 404 only in the API layer, keep domain errors typed"],"tags":["validation","domain-not-found","python","orchestrator"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}