sipeed/picoclaw · error
error starting channels: %w
Error message
error starting channels: %w
What it means
One or more channel backends failed to start when ChannelManager.StartAll ran after HTTP listeners were wired. StartAll iterates every enabled channel calling channel.Start(ctx) and aggregates failures as 'channel <name>: <err>', so the wrapped message identifies which channel broke.
Source
Thrown at pkg/gateway/gateway.go:501
}
runningServices.authToken = authToken
runningServices.HealthServer = health.NewServer(listenResult.ProbeHost, cfg.Gateway.Port, authToken)
var listenAddr string
if len(listenResult.Listeners) > 0 {
listenAddr = listenResult.Listeners[0].Addr().String()
} else {
listenAddr = net.JoinHostPort(listenResult.ProbeHost, strconv.Itoa(cfg.Gateway.Port))
}
runningServices.ChannelManager.SetupHTTPServerListeners(
listenResult.Listeners,
listenAddr,
runningServices.HealthServer,
)
if err = runningServices.ChannelManager.StartAll(context.Background()); err != nil {
return nil, fmt.Errorf("error starting channels: %w", err)
}
logChannelVoiceCapabilities(runningServices.ChannelManager, transcriber != nil, ttsAvailable)
if transcriber != nil {
// Start Voice Agent Orchestrator after channels are ready.
vaCtx, vaCancel := context.WithCancel(context.Background())
runningServices.VoiceAgentCancel = vaCancel
voiceAgent := asr.NewAgent(msgBus, transcriber)
voiceAgent.Start(vaCtx)
}
healthAddr := net.JoinHostPort(listenResult.ProbeHost, strconv.Itoa(cfg.Gateway.Port))
fmt.Printf(
"✓ Health endpoints available at http://%s/health, /ready and /reload (POST)\n",
healthAddr,
)
View on GitHub (pinned to 49183d7e8d)
Solutions
- Read the wrapped per-channel errors in the returned message
- Re-validate tokens/credentials for each named channel and refresh them
- Check network connectivity/egress rules for the channel APIs
- Kill stale gateway processes holding ports, then retry startup
- Temporarily set failing channels enabled:false to isolate the rest
Defensive patterns
Strategy: try-catch
Validate before calling
// before StartAll: cheap credential probe per channel where the SDK offers one (e.g. telegram getMe)
Try / catch
if err = cm.StartAll(ctx); err != nil {
// err aggregates 'channel <name>: <cause>'; parse names to disable-and-retry
log.Printf("failed channels: %v", err)
} Prevention
- Validate channel tokens before restart (provider API probes)
- Monitor port availability for listener channels
- Disable broken channels instead of failing the whole boot
When it happens
Trigger: A channel's Start() failing: invalid Telegram bot token, WhatsApp/Slack webhook unreachable or auth rejected, port already bound by a channel listener; StartAll cancels its dispatch task when no channel starts and returns the joined error, which gateway.go wraps as 'error starting channels'.
Common situations: Expired or rotated API tokens; network egress blocked by firewall/proxy; another instance of the gateway still holding the port; channel API version changes after upgrade.
Related errors
- error creating channel manager: %w
- failed to open discord session: %w
- error starting heartbeat service: %w
- must be in range 1-65535
- after %d retries: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/f52874beedd14836.
Report an issue: GitHub.