sipeed/picoclaw · error
failed to open discord session: %w
Error message
failed to open discord session: %w
What it means
session.Open() failed while establishing the Discord WebSocket gateway connection. It fires after credentials already validated (User("@me") succeeded), so the cause is gateway-specific: network/proxy blocking wss, Discord gateway outage, or a session problem — not the token itself.
Source
Thrown at pkg/channels/discord/discord.go:124
func (c *DiscordChannel) Start(ctx context.Context) error {
logger.InfoC("discord", "Starting Discord bot")
c.ctx, c.cancel = context.WithCancel(ctx)
// Get bot user ID before opening session to avoid race condition
botUser, err := c.session.User("@me")
if err != nil {
return fmt.Errorf("failed to get bot user: %w", err)
}
c.botUserID = botUser.ID
c.session.AddHandler(c.handleMessage)
go c.listenVoiceControl(c.ctx)
if err := c.session.Open(); err != nil {
return fmt.Errorf("failed to open discord session: %w", err)
}
c.SetRunning(true)
logger.InfoCF("discord", "Discord bot connected", map[string]any{
"username": botUser.Username,
"user_id": botUser.ID,
})
return nil
}
func (c *DiscordChannel) Stop(ctx context.Context) error {
logger.InfoC("discord", "Stopping Discord bot")
c.SetRunning(false)
// Stop all typing goroutines before closing session
c.typingMu.Lock()View on GitHub (pinned to 49183d7e8d)
Solutions
- Confirm websocket-capable egress to gateway.discord.gg:443 (test with a websocket client or wscat)
- Remove or replace proxies that cannot tunnel wss; verify socks5/http CONNECT works
- Check status.discord.com during incidents and retry Start with backoff
- Ensure Start is only called once per session lifecycle (Stop between restarts)
Defensive patterns
Strategy: retry
Validate before calling
// Confirm websocket egress before Start (gateway reachable?)
// quick probe: TLS connect to gateway.discord.gg:443
conn, err := net.DialTimeout("tcp", "gateway.discord.gg:443", 5*time.Second)
if err != nil {
return fmt.Errorf("cannot reach discord gateway: %w", err)
}
conn.Close() Try / catch
err := backoff.Retry(func() error {
if err := ch.Start(ctx); err != nil {
if strings.Contains(err.Error(), "failed to open discord session") {
return fmt.Errorf("gateway open: %w", err) // retryable
}
return backoff.Permanent(err)
}
return nil
}, backoff.NewExponentialBackOff()) Prevention
- Ensure the proxy (cfg.Proxy or HTTP(S)_PROXY) supports websocket upgrades / CONNECT
- Check status.discord.com during incidents instead of tight-loop retrying
- Call Start only once per session; Stop between restarts
- Enable required privileged intents in the Developer Portal so the gateway does not reject the session
When it happens
Trigger: Start() when egress to gateway.discord.gg:443 (websocket) is blocked while REST works, a proxy that does not support websocket upgrades, Discord outage/maintenance on the gateway, or calling Start on an already-open session.
Common situations: Corporate firewalls allowing HTTPS APIs but killing long-lived websockets, HTTP-only proxies applied via cfg.Proxy or env, Discord status incidents, restarting the channel twice without Stop.
Related errors
- failed to start stream client: %w
- failed to get websocket info: %w
- error starting channels: %w
- Gateway unavailable: %v
- failed to create discord session: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/09cf756f1079c942.
Report an issue: GitHub.