{"record":{"id":"c0a8cc8e287362dc","repo":"ruvnet/RuView","slug":"router-router-id-not-found","errorCode":null,"errorMessage":"Router '{router_id}' not found","messagePattern":"Router '(.+?)' not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"archive/v1/src/api/dependencies.py","lineNumber":223,"sourceCode":"                status_code=status.HTTP_403_FORBIDDEN,\n                detail=f\"Access denied to zone '{zone_id}'\"\n            )\n    \n    return zone_id\n\n\n# Router access dependencies\nasync def validate_router_access(\n    router_id: str,\n    current_user: Optional[Dict[str, Any]] = Depends(get_current_user)\n) -> str:\n    \"\"\"Validate user access to a specific router.\"\"\"\n    domain_config = get_domain_config()\n    \n    # Check if router exists\n    router = domain_config.get_router(router_id)\n    if not router:\n        raise HTTPException(\n            status_code=status.HTTP_404_NOT_FOUND,\n            detail=f\"Router '{router_id}' not found\"\n        )\n    \n    # Check if router is enabled\n    if not router.enabled:\n        raise HTTPException(\n            status_code=status.HTTP_403_FORBIDDEN,\n            detail=f\"Router '{router_id}' is disabled\"\n        )\n    \n    # If authentication is enabled, check user access\n    if current_user:\n        # Admin users have access to all routers\n        if current_user.get(\"is_admin\", False):\n            return router_id\n        \n        # Check user's router permissions","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/api/dependencies.py#L205-L241","documentation":"validate_router_access raises 404 \"Router '<router_id>' not found\" when domain_config.get_router(router_id) returns None — the router id is not in the loaded domain configuration. It is the router analogue of the zone-not-found check and runs before permission checks.","triggerScenarios":"A path parameter router_id that matches no configured router (typo, stale id); router config not loaded; the router entry was removed after clients cached its id.","commonSituations":"Renamed or decommissioned ESP32 router nodes; config file not mounted in the deployment; client hardcoded ids drifting from server config.","solutions":["List configured routers (routers API or domain config) and use an exact id","Verify the domain configuration file loaded and contains the router entry","Fix typos/case in the router id"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Discover router ids before calling router-scoped routes\nrouters = client.get('/api/routers', headers=auth).json()\nvalid = {r['id'] for r in routers}\nif router_id not in valid:\n    raise ValueError(f'Unknown router {router_id!r}; valid: {sorted(valid)}')","typeGuard":null,"tryCatchPattern":"try:\n    r = client.get(f'/api/routers/{router_id}', headers=auth)\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        refresh_router_list()  # node may have been renamed or decommissioned\n    raise","preventionTips":["Read router ids from the API rather than hardcoding hardware names","Refresh cached router ids after node re-provisioning","Watch for case drift between config ids and client strings"],"tags":["routers","http-404","configuration","python"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}