{"record":{"id":"dacd44e7a0b79244","repo":"ruvnet/RuView","slug":"unknown-service-service-name","errorCode":null,"errorMessage":"Unknown service: {service_name}","messagePattern":"Unknown service: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"archive/v1/src/api/dependencies.py","lineNumber":266,"sourceCode":"    \n    return router_id\n\n\n# Service health dependencies\nasync def check_service_health(\n    request: Request,\n    service_name: str\n) -> bool:\n    \"\"\"Check if a service is healthy.\"\"\"\n    try:\n        if service_name == \"pose\":\n            service = getattr(request.app.state, 'pose_service', None)\n        elif service_name == \"stream\":\n            service = getattr(request.app.state, 'stream_service', None)\n        elif service_name == \"hardware\":\n            service = getattr(request.app.state, 'hardware_service', None)\n        else:\n            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail=f\"Unknown service: {service_name}\"\n            )\n        \n        if not service:\n            raise HTTPException(\n                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,\n                detail=f\"Service '{service_name}' not available\"\n            )\n        \n        # Check service health\n        status_info = await service.get_status()\n        if status_info.get(\"status\") != \"healthy\":\n            raise HTTPException(\n                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,\n                detail=f\"Service '{service_name}' is unhealthy: {status_info.get('error', 'Unknown error')}\"\n            )\n        ","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/api/dependencies.py#L248-L284","documentation":"check_service_health raises 400 'Unknown service: {service_name}' when the name it receives is not one of the three hardcoded names mapped to app.state attributes: 'pose' (pose_service), 'stream' (stream_service), or 'hardware' (hardware_service). It is a client-side input error, not a server health problem.","triggerScenarios":"Calling the health dependency/route with service_name like 'inference', 'model', 'api', or a typo such as 'pose '; adding a new service to app.state without extending the if/elif chain in this function.","commonSituations":"Client and server disagreeing on service names; copy-pasted route parameters; new services registered at startup but forgotten in the health checker.","solutions":["Use exactly one of: pose, stream, hardware","When adding a new service, extend the chain (or replace it with a dict registry name -> app.state attribute)","Validate the parameter client-side before calling"],"exampleFix":"# before\nif service_name == 'pose':\n    service = getattr(request.app.state, 'pose_service', None)\nelif ...\nelse:\n    raise HTTPException(400, f'Unknown service: {service_name}')\n\n# after: registry, so new services need one line\nSERVICE_ATTRS = {'pose': 'pose_service', 'stream': 'stream_service', 'hardware': 'hardware_service'}\nattr = SERVICE_ATTRS.get(service_name)\nif attr is None:\n    raise HTTPException(status_code=400, detail=f'Unknown service: {service_name}')\nservice = getattr(request.app.state, attr, None)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"KNOWN_SERVICES = frozenset({'pose', 'stream', 'hardware'})\n\ndef is_known_service(name: str) -> bool:\n    \"\"\"True when name is one of the services check_service_health maps to app.state.\"\"\"\n    return name in KNOWN_SERVICES\n\n# guard before the call\nif not is_known_service(service_name):\n    raise ValueError(f'service must be one of {sorted(KNOWN_SERVICES)}, got {service_name!r}')","tryCatchPattern":"try:\n    r = client.get(f'/api/health/{service_name}')\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 400:\n        # unknown name: fix the caller's vocabulary, do not retry\n        raise ValueError(f'Unsupported service name: {service_name}') from e\n    raise","preventionTips":["Define service names as constants shared between client and server","Extend the check_service_health registry whenever a new service is added to app.state","Treat 400 here as a programming error, not a runtime failure"],"tags":["health-check","http-400","python","fastapi"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}