{"record":{"id":"731dc5eaa24759fc","repo":"ruvnet/RuView","slug":"service-service-name-is-unhealthy-status-inf","errorCode":null,"errorMessage":"Service '{service_name}' is unhealthy: {status_info.get('error', 'Unknown error')}","messagePattern":"Service '(.+?)' is unhealthy: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":503,"severity":"error","filePath":"archive/v1/src/api/dependencies.py","lineNumber":280,"sourceCode":"            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        \n        return True\n        \n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"Error checking service health for {service_name}: {e}\")\n        raise HTTPException(\n            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,\n            detail=f\"Service '{service_name}' health check failed\"\n        )\n\n\n# Rate limiting dependencies\nasync def check_rate_limit(","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/api/dependencies.py#L262-L298","documentation":"check_service_health raises 503 \"Service '<name>' is unhealthy: <error>\" when the service object exists and its get_status() call succeeds but reports status != 'healthy'. The underlying error text from the service's own status dict is forwarded into the message, making this the informative variant of the two 503s.","triggerScenarios":"The pose service reporting degraded because its model/inference backend is unreachable; the stream service unhealthy because no CSI feed is connected; the hardware service failing its device probe — each returned by service.get_status() with status 'unhealthy'/'degraded' rather than 'healthy'.","commonSituations":"Backend dependencies down (model server, CSI collector, serial device); post-crash services that restarted but have not re-validated their dependencies; partial infra outages.","solutions":["Read the error text embedded in the detail — it is the service's own get_status() error and names the failing dependency","Restore the named dependency (model backend, stream source, hardware device) and re-check","Check the service's logs for the same error to get the full traceback","Keep readiness probes pointed at this endpoint so traffic stops while unhealthy"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    r = client.get(f'/api/health/{service_name}')\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    detail = e.response.json().get('detail', '')\n    if e.response.status_code == 503 and 'is unhealthy' in detail:\n        # detail carries the service's own error: log it, back off, retry\n        logger.warning('service degraded: %s', detail)\n        await asyncio.sleep(backoff)\n        r = client.get(f'/api/health/{service_name}')\n    raise","preventionTips":["Parse the embedded error text from the 503 detail — it names the failing dependency","Wire readiness probes to this endpoint so unhealthy services stop receiving traffic","Alert on sustained 'unhealthy' rather than single blips"],"tags":["health-check","http-503","python","diagnostics"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}