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
- If encountered after modifying message structs, verify msg.Content and msg.ChatID remain strings.
- 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
- No runtime prevention needed for an all-string payload.
- If refactoring OutboundMessage field types, keep them JSON-marshalable to preserve this guarantee.
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
- ${label} must be a JSON object.
- ${label}.${key} must be a string.
- Failed to save config
- marshal result: %w
- marshal request: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/7417e7ad7438973c.
Report an issue: GitHub.