Skip to content

[Bug] Discord channel returns 'bad request' when sending empty text with media #9408

@huaguihai

Description

@huaguihai

Bug Description

Discord channel frequently returns "bad request" errors when sending messages, while WhatsApp channel works fine with the same configuration.

Root Cause Analysis

After investigating the codebase, I found the following issues:

1. Empty text validation missing in sendDiscordMedia()

Location: dist/discord/send.shared.js

sendDiscordText() validates non-empty text (line 205-206):

if (!text.trim()) {
    throw new Error("Message must be non-empty for Discord sends");
}

But sendDiscordMedia() has no such validation, allowing empty captions to be sent:

const caption = chunks[0] ?? "";  // Can be empty string
// ...
body: {
    content: caption || undefined,  // undefined when empty
    files: [...]
}

Discord API requires at least one non-empty field (content, embeds, files with content, etc.). When only files is present with content: undefined, Discord returns 400 Bad Request.

2. Multi-media reply sends empty text

Location: dist/discord/monitor/reply-delivery.js line 53

for (const extra of mediaList.slice(1)) {
    await sendMessageDiscord(params.target, "", {  // Empty text!
        token: params.token,
        rest: params.rest,
        mediaUrl: extra,
        accountId: params.accountId,
    });
}

When there are multiple media files, the 2nd+ media are sent with empty text "", causing bad request.

3. Retry policy doesn't handle 400 errors

Location: dist/infra/retry-policy.js line 33-51

shouldRetry: (err) => err instanceof RateLimitError,  // Only retries 429

400 Bad Request errors are not retried, directly returned to user as "bad request".

Reproduction Steps

  1. Configure Discord channel in openclaw
  2. Ask the bot to respond with multiple images or files
  3. First message succeeds, subsequent media messages fail with "bad request"

Or:

  1. Trigger a response that results in empty text + media (edge case in message chunking)

Expected Behavior

  • Empty text should be validated before sending
  • Multi-media messages should have proper content or be handled differently
  • Error messages should be more descriptive

Environment

  • OpenClaw version: 2026.2.1
  • Node.js version: v24.x
  • Platform: Linux

Suggested Fix

  1. Add empty text validation in sendDiscordMedia() similar to sendDiscordText()
  2. In reply-delivery.js, either:
    • Add a placeholder text for additional media (e.g., "📎")
    • Or skip sending if both text and meaningful content are empty
  3. Consider adding request body validation before calling Discord API

Comparison with WhatsApp

WhatsApp channel works fine because:

  • Higher character limit (4000 vs 2000)
  • Different message handling through gateway
  • Less strict API validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions