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

  1. Fix the caller to always set ChatID to the Discord channel snowflake ID from the inbound message
  2. Add validation/logging at the message-bus publish site so empty ChatID is caught with producer context
  3. 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

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


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/c16cb45e414f6f73. Report an issue: GitHub.