Skip to content

Telegram sink fails with "can't parse entities" due to unescaped Markdown #1982

@m-minasyan

Description

@m-minasyan

Bug: Telegram sink fails with "can't parse entities" due to unescaped Markdown

Describe the bug

The Telegram sink uses parse_mode: "Markdown" but does not escape special Markdown characters in message content. When alert text contains underscores (common in Kubernetes pod names like crowdsec-agent_k8vkt), Telegram interprets them as italic markers and fails to parse the message.

Error message

Failed to send telegram message: chat_id - -100xxxxxxxxx reason - Bad Request
{"ok":false,"error_code":400,"description":"Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 294"}

Root cause

In src/robusta/core/sinks/telegram/telegram_client.py, the send_message method uses:

"parse_mode": "Markdown",
"text": message,

The message content is not escaped before sending. Markdown special characters (_, *, `, [, ]) in pod names, error messages, or other Kubernetes resources cause parsing failures.

Expected behavior

Either:

  1. Escape Markdown special characters before sending (replace _ with _, etc.)
  2. Add a parse_mode parameter to TelegramSinkParams allowing users to choose Markdown, MarkdownV2, HTML, or empty string (plain text)
  3. Use HTML mode by default with proper html.escape() on message content

Robusta version

  • robusta-runner: 0.31.1
  • Helm chart: 0.31.1

Suggested fix

Option A - Add escaping (minimal change):

import re

def escape_markdown(text: str) -> str:
    """Escape Markdown special characters."""
    escape_chars = r'_*`['
    return re.sub(f'([{re.escape(escape_chars)}])', r'\\\1', text)

# In send_message:
"text": escape_markdown(message),

Option B - Add parse_mode parameter to TelegramSinkParams:

class TelegramSinkParams(SinkBaseParams):
    bot_token: str
    chat_id: Union[int, str]
    thread_id: Optional[int] = None
    send_files: bool = True
    parse_mode: Optional[str] = "Markdown"  # NEW: Allow None for plain text

Additional context
This affects any Kubernetes cluster where resource names contain underscores, which is extremely common. The issue is intermittent - only alerts with unbalanced special characters fail.

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