sipeed/picoclaw · info

failed to marshal message: %w

Error message

failed to marshal message: %w

What it means

Returned when json.Marshal fails on the outbound payload map {type, to, content} in the WhatsApp bridge channel's Send. Because all three values are Go strings, this branch is effectively unreachable in practice - encoding/json never fails on string values (invalid UTF-8 is replaced with U+FFFD). Marshal only errors on unsupported types (chan, func, complex, NaN/Inf floats) which cannot occur here.

Source

Thrown at pkg/channels/whatsapp/whatsapp.go:138

	default:
	}

	c.mu.Lock()
	defer c.mu.Unlock()

	if c.conn == nil {
		return nil, fmt.Errorf("whatsapp connection not established: %w", channels.ErrTemporary)
	}

	payload := map[string]any{
		"type":    "message",
		"to":      msg.ChatID,
		"content": msg.Content,
	}

	data, err := json.Marshal(payload)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal message: %w", err)
	}

	_ = c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
	if err := c.conn.WriteMessage(websocket.TextMessage, data); err != nil {
		_ = c.conn.SetWriteDeadline(time.Time{})
		return nil, fmt.Errorf("whatsapp send: %w", channels.ErrTemporary)
	}
	_ = c.conn.SetWriteDeadline(time.Time{})

	return nil, nil
}

func (c *WhatsAppChannel) listen() {
	for {
		select {
		case <-c.ctx.Done():
			return
		default:

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. If encountered after modifying message structs, verify msg.Content and msg.ChatID remain strings.
  2. No action needed otherwise - this is defensive dead code for an all-string payload.
Defensive patterns

Strategy: validation

Try / catch

if _, err := ch.Send(ctx, msg); err != nil && strings.Contains(err.Error(), "failed to marshal message") {
    // unreachable in current code; treat as a bug and report upstream
}

Prevention

When it happens

Trigger: Theoretically only if msg.Content or msg.ChatID were changed to a non-marshalable type in a future refactor of bus.OutboundMessage. No runtime input can trigger it today.

Common situations: Essentially never hit; appears in error catalogues as dead defensive code. If it does appear after a refactor, a field type changed to something json cannot encode.

Related errors


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