sipeed/picoclaw · error
no agent available for route (agent_id=%s)
Error message
no agent available for route (agent_id=%s)
What it means
Every inbound message is routed: AgentRegistry.ResolveRoute maps the inbound context (channel/chat) to a ResolvedRoute with an AgentID; the loop then tries GetAgent(route.AgentID) and falls back to GetDefaultAgent(). This error fires when the routed agent_id does not exist in the registry AND no fallback agent exists — there is literally no agent to hand the message to.
Source
Thrown at pkg/agent/agent_message.go:230
"session_key": opts.Dispatch.SessionKey,
"skills": strings.Join(pending, ","),
})
}
return al.runAgentLoop(ctx, agent, opts)
}
func (al *AgentLoop) resolveMessageRoute(msg bus.InboundMessage) (routing.ResolvedRoute, *AgentInstance, error) {
registry := al.GetRegistry()
inboundCtx := normalizedInboundContext(msg)
route := registry.ResolveRoute(inboundCtx)
agent, ok := registry.GetAgent(route.AgentID)
if !ok {
agent = registry.GetDefaultAgent()
}
if agent == nil {
return routing.ResolvedRoute{}, nil, fmt.Errorf("no agent available for route (agent_id=%s)", route.AgentID)
}
return route, agent, nil
}
func (al *AgentLoop) allocateRouteSession(route routing.ResolvedRoute, msg bus.InboundMessage) session.Allocation {
return session.AllocateRouteSession(session.AllocationInput{
AgentID: route.AgentID,
Context: normalizedInboundContext(msg),
SessionPolicy: route.SessionPolicy,
})
}
func (al *AgentLoop) processSystemMessage(
ctx context.Context,
msg bus.InboundMessage,
) (string, error) {
if msg.Channel != "system" {View on GitHub (pinned to 49183d7e8d)
Solutions
- Look at the agent_id in the message and either add that agent to config or fix the routing entry that references it
- Keep at least one healthy agent registered so the GetDefaultAgent fallback can absorb unknown routes
- Validate routing rules against agents.list ids at startup (CI config lint)
- Restart picoclaw after fixing config; routes are resolved per message so no cached state is involved
Example fix
// config — before: route points at nonexistent agent id
"routing": { "rules": [ { "channel": "telegram", "agent_id": "asistant" } ] }
"agents": { "list": [ { "id": "assistant", "model_name": "gpt-4o-mini" } ] }
// after: ids match
"routing": { "rules": [ { "channel": "telegram", "agent_id": "assistant" } ] }
"agents": { "list": [ { "id": "assistant", "model_name": "gpt-4o-mini" } ] } Defensive patterns
Strategy: validation
Validate before calling
ids := al.GetRegistry().ListAgentIDs()
known := make(map[string]bool, len(ids))
for _, id := range ids {
known[id] = true
}
for _, rule := range cfg.Routing.Rules { // adapt to your routing config shape
if rule.AgentID != "" && !known[rule.AgentID] {
return fmt.Errorf("routing rule references unknown agent %q", rule.AgentID)
}
} Prevention
- Keep one healthy default agent registered so unknown routes fall back instead of failing
- Lint routing rules against agents.list ids in CI
- When removing/renaming an agent, grep config for its id before deploying
When it happens
Trigger: A routing rule or channel-to-agent mapping resolves to an agent id that is not in agents.list, while the registry is empty or contains no other usable agent for the fallback. The %s in the message shows the unresolved agent_id.
Common situations: Typo in a routing rule's agent id; an agent removed or renamed in config while routing rules still point at the old id; agents.list failed to load (provider errors) so even the fallback is missing.
Related errors
- no default agent for heartbeat
- no default agent for system message
- ✗ registry '%s' not found or not enabled. check your config
- channel %s not found
- failed to load MCP servers: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/57b3bc8ce9bb12fe.
Report an issue: GitHub.