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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions