ruvnet/RuView · error · ValueError
Router {router_id} not found
Error message
Router {router_id} not found What it means
HardwareService.get_router_status() looks up router_id in the in-memory router_interfaces mapping, which is populated when routers are registered during service initialization. An unknown id raises ValueError immediately, before any hardware I/O. In practice this means the router was never registered (initialize not run or failed for that router) or the id string does not match the configured one.
Source
Thrown at archive/v1/src/services/hardware_service.py:308
time_diffs = []
for i in range(1, len(recent_samples)):
try:
t1 = datetime.fromisoformat(recent_samples[i-1]["timestamp"])
t2 = datetime.fromisoformat(recent_samples[i]["timestamp"])
diff = (t2 - t1).total_seconds()
if diff > 0:
time_diffs.append(diff)
except Exception:
continue
if time_diffs:
avg_interval = sum(time_diffs) / len(time_diffs)
self.stats["average_sample_rate"] = 1.0 / avg_interval if avg_interval > 0 else 0.0
async def get_router_status(self, router_id: str) -> Dict[str, Any]:
"""Get status of a specific router."""
if router_id not in self.router_interfaces:
raise ValueError(f"Router {router_id} not found")
interface = self.router_interfaces[router_id]
try:
is_healthy = await interface.check_health()
status = await interface.get_status()
return {
"router_id": router_id,
"healthy": is_healthy,
"connected": status.get("connected", False),
"last_data_time": status.get("last_data_time"),
"error_count": status.get("error_count", 0),
"configuration": status.get("configuration", {})
}
except Exception as e:
return {View on GitHub (pinned to 4685618388)
Solutions
- List what is actually registered: read service.router_interfaces.keys() or the service's get_status() output, and use one of those ids.
- Ensure the service lifecycle completed: 'await hardware_service.initialize()' before querying, and check last_error for registration failures.
- Correct the router id in the caller/config (exact string, correct case).
- If a router is genuinely missing, add it to the hardware configuration so initialize() registers it.
Example fix
# before
status = await hardware_service.get_router_status('router_2') # ValueError
# after
if 'router_2' not in hardware_service.router_interfaces:
raise KeyError(f"unknown router; registered: {sorted(hardware_service.router_interfaces)}")
status = await hardware_service.get_router_status('router_2') Defensive patterns
Strategy: validation
Validate before calling
known = set(hardware_service.router_interfaces)
if router_id not in known:
raise KeyError(f'unknown router {router_id}; registered: {sorted(known)}')
status = await hardware_service.get_router_status(router_id) Prevention
- Expose the registered router ids via your API (derived from router_interfaces) and have clients use those ids.
- Validate user-supplied router ids at the request boundary before touching the service.
- Ensure initialize() completed (and check last_error) before serving router status queries.
When it happens
Trigger: Calling get_router_status('router_2') when the service only registered 'router_1'; querying after a failed initialize() that left router_interfaces empty; passing an id with different casing or whitespace than configured.
Common situations: API handlers forwarding user-supplied router ids without validation; config drift where .env lists fewer routers than the dashboard expects; calling status right after process start before initialize() completes.
Related errors
- Hardware service is not running
- Atheros CSI format parsing is not yet implemented. The Ather
- Unsupported hardware type: {self.hardware_type}
- Service not found: {service_name}
- Pose service is not running
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/fce91549d464e68c.
Report an issue: GitHub.