Skip to content

WhatsApp channel: HTML tags (e.g. <br>) not stripped before delivery #31884

@AytuncYildizli

Description

@AytuncYildizli

Bug

When the model output contains HTML tags like <br>, they are sent as literal text to WhatsApp instead of being converted or stripped.

Expected Behavior

WhatsApp is a plain-text surface. HTML tags should be:

  • <br> / <br/> → converted to \n
  • Other HTML tags → stripped (or converted to WhatsApp formatting where applicable, e.g. <b>*bold*)

Actual Behavior

HTML tags appear as literal text in WhatsApp messages. For example, the user sees <br> in the middle of a message.

Root Cause

Investigation of dist/deliver-*.js confirms there is no HTML sanitization/stripping function in the WhatsApp delivery pipeline. Searched for formatMessage, stripHtml, sanitize — all returned empty.

The delivery flow in normalizeReplyPayloadsForDelivery() processes media URLs, reply tags, and audio tags, but does not touch HTML content in the text body.

Suggested Fix

Add a surface-aware text sanitizer in the delivery pipeline that runs before sending to non-HTML surfaces (WhatsApp, Signal, SMS, IRC, etc.):

function sanitizeForPlainTextSurface(text: string): string {
  return text
    .replace(/<br\s*\/?>/gi, "\n")
    .replace(/<\/?(b|strong)>/gi, "*")
    .replace(/<\/?(i|em)>/gi, "_")
    .replace(/<\/?(s|strike|del)>/gi, "~")
    .replace(/<[^>]+>/g, ""); // strip remaining tags
}

Environment

  • OpenClaw v2026.3.1-beta.1
  • Channel: WhatsApp (via whatsapp-web.js)
  • Model: Claude Opus 4.6 (but affects any model that produces HTML)

Labels

bug, whatsapp, delivery

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions