sipeed/picoclaw · error
channel ID is empty
Error message
channel ID is empty
What it means
Send refuses to deliver an OutboundMessage whose ChatID is blank — there is no Discord channel snowflake to address, so delivery is impossible. This is a caller-side data bug in whatever produced the outbound message, not a Discord API failure.
Source
Thrown at pkg/channels/discord/discord.go:171
if c.progress != nil {
c.progress.StopAll()
}
if err := c.session.Close(); err != nil {
return fmt.Errorf("failed to close discord session: %w", err)
}
return nil
}
func (c *DiscordChannel) Send(ctx context.Context, msg bus.OutboundMessage) ([]string, error) {
if !c.IsRunning() {
return nil, channels.ErrNotRunning
}
channelID := msg.ChatID
if channelID == "" {
return nil, fmt.Errorf("channel ID is empty")
}
if len([]rune(msg.Content)) == 0 {
return nil, nil
}
isToolFeedback := outboundMessageIsToolFeedback(msg)
if isToolFeedback {
if msgID, handled, err := c.progress.Update(ctx, channelID, msg.Content); handled {
if err != nil {
return nil, err
}
return []string{msgID}, nil
}
}
trackedMsgID, hasTrackedMsg := c.currentToolFeedbackMessage(channelID)
c.maybeStartTTS(channelID, msg.Content, isToolFeedback)
if !isToolFeedback {View on GitHub (pinned to 49183d7e8d)
Solutions
- Fix the caller to always set ChatID to the Discord channel snowflake ID from the inbound message
- Add validation/logging at the message-bus publish site so empty ChatID is caught with producer context
- Write a unit test asserting outbound messages never have an empty ChatID
Example fix
// before
bus.Publish(bus.OutboundMessage{Content: reply}) // ChatID zero value
// after
bus.Publish(bus.OutboundMessage{ChatID: inbound.ChatID, Content: reply}) Defensive patterns
Strategy: validation
Validate before calling
if msg.ChatID == "" {
return fmt.Errorf("refusing to publish outbound message with empty ChatID (source: %s)", producer)
} Prevention
- Always copy ChatID from the inbound context when building outbound messages
- Validate at the message-bus publish boundary with producer context in the error
- Cover the empty-ChatID case in unit tests of every new producer
When it happens
Trigger: A producer publishes bus.OutboundMessage with an empty ChatID: agent/session wiring losing the original chat ID, scheduled or proactive sends constructed without a target, tests building messages without ChatID.
Common situations: New message-bus producers (cron jobs, webhooks, tools) forgetting to copy ChatID from the inbound context, refactors that rename or drop the field.
Related errors
- discord send: %w
- invalid discord proxy URL %q: %w
- matrix room ID is empty: %w
- ${label} must be a JSON object.
- ${label}.${key} must be a string.
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/c16cb45e414f6f73.
Report an issue: GitHub.