hermes - ✅(Solved) Fix Discord mixed attachments can be misclassified as text when the first attachment is unsupported [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#15701Fetched 2026-04-26 05:25:41
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×4commented ×2cross-referenced ×1

Fix Action

Fix / Workaround

  • gateway/platforms/discord.py:3264-3285 — message type detection loops over message.attachments but unconditionally breaks after the first attachment with a content_type.
  • gateway/platforms/discord.py:3320-3405 — later attachments are still downloaded/cached into media_urls/media_types, so the event can contain image media while being classified as MessageType.TEXT.
  • gateway/platforms/discord.py:3450-3455 — only MessageType.TEXT is batched; misclassified media messages can be delayed/merged like normal text instead of dispatched immediately.

A single unsupported leading attachment changes the behavior of a supported later attachment. The downstream event can contain media_urls=['/tmp/cached_image.png'] and media_types=['image/png'] while message_type == MessageType.TEXT, which contradicts the media payload and bypasses the intended immediate media dispatch path.

PR fix notes

PR #15816: fix(discord): scan all attachments for type; don't stop at first unrecognized (#15701)

Description (problem / solution / changelog)

Summary

  • The msg_type detection loop in DiscordAdapter._handle_message() unconditionally breaked after the first attachment that had any content_type string, even if that type was unrecognised (e.g. application/octet-stream)
  • A mixed message with an unsupported file first and an image second was classified as TEXT, bypassing the vision tool and causing the message to be silently batched instead of dispatched as PHOTO
  • The media-download loop already iterates all attachments correctly; this fix aligns the classification loop with it

The bug

gateway/platforms/discord.py — classification loop (pre-fix):

for att in message.attachments:
    if att.content_type:
        if att.content_type.startswith("image/"):
            msg_type = MessageType.PHOTO
        elif att.content_type.startswith("video/"):
            msg_type = MessageType.VIDEO
        elif att.content_type.startswith("audio/"):
            msg_type = MessageType.AUDIO
        else:
            ...
            if doc_ext in SUPPORTED_DOCUMENT_TYPES:
                msg_type = MessageType.DOCUMENT
    break   # ← breaks after first attachment with any content_type

When attachment[0] is application/octet-stream (not a supported document extension), msg_type stays TEXT and break fires — attachment[1]'s image/png is never inspected.

The fix

Moved each break inside its own recognized-type branch. Unrecognised attachment types fall through the if att.content_type: block without setting a type and without breaking, so the loop continues to the next attachment.

Also fixes the make_message test helper (added guild=None and bot=False on the author stub) which was broken by a recent upstream addition of guild_id to the build_source call — restoring the pre-existing TestIncomingDocumentHandling tests that had become red on main.

Test plan

  • Before: test_unsupported_first_recognized_image_secondhandle_message was never called (message batched as TEXT); call_args was NoneTypeError
  • After: 4 new tests in TestAttachmentTypeDetection all pass; 11 pre-existing tests restored to green
  • Regression guard: reverted gateway/platforms/discord.pytest_unsupported_first_recognized_image_second failed; restored → 15 tests green
  • Adjacent suites unchanged: test_discord_attachment_download baseline unchanged

Related

  • Fixes #15701

🤖 Generated with Claude Code

Changed files

  • gateway/platforms/discord.py (modified, +9/-2)
  • tests/gateway/test_discord_document_handling.py (modified, +87/-1)

Code Example

[Discord] Unsupported document type '.exe' (application/octet-stream), skipping
[Discord] Cached user image: /tmp/cached_image.png
message_type= MessageType.TEXT expected= MessageType.PHOTO
media_urls= ['/tmp/cached_image.png'] media_types= ['image/png']
RAW_BUFFERClick to expand / collapse

Bug

Discord incoming attachment classification stops after inspecting the first attachment. If the first attachment is unsupported or fails the document path but a later attachment is a supported image/audio/video/document, _handle_message() still leaves event.message_type as TEXT or the first attachment's type.

Affected files/lines

  • gateway/platforms/discord.py:3264-3285 — message type detection loops over message.attachments but unconditionally breaks after the first attachment with a content_type.
  • gateway/platforms/discord.py:3320-3405 — later attachments are still downloaded/cached into media_urls/media_types, so the event can contain image media while being classified as MessageType.TEXT.
  • gateway/platforms/discord.py:3450-3455 — only MessageType.TEXT is batched; misclassified media messages can be delayed/merged like normal text instead of dispatched immediately.

Why this is a bug

A single unsupported leading attachment changes the behavior of a supported later attachment. The downstream event can contain media_urls=['/tmp/cached_image.png'] and media_types=['image/png'] while message_type == MessageType.TEXT, which contradicts the media payload and bypasses the intended immediate media dispatch path.

Minimal reproduction

Using the existing Discord adapter test fakes, send a DM with two attachments:

  1. malware.exe with content_type='application/octet-stream' (unsupported document)
  2. photo.png with content_type='image/png'

Observed from a narrow local repro:

[Discord] Unsupported document type '.exe' (application/octet-stream), skipping
[Discord] Cached user image: /tmp/cached_image.png
message_type= MessageType.TEXT expected= MessageType.PHOTO
media_urls= ['/tmp/cached_image.png'] media_types= ['image/png']

The selected gateway test chunk passes today (250 passed), but there is no coverage for mixed unsupported+supported attachment ordering.

Expected behavior

Attachment type detection should consider all attachments until it finds a supported media/document type, or derive the final event type from the successfully cached media_types/media_urls. A leading unsupported attachment should not cause a later supported image/audio/video/document to be treated as plain text.

Suggested investigation direction

Add a regression test near tests/gateway/test_discord_document_handling.py::test_image_attachment_unaffected for [unsupported, image] ordering, then adjust the loop at gateway/platforms/discord.py:3270-3285 so it only breaks after selecting a supported type (or prioritizes supported media across the full attachment list).

extent analysis

TL;DR

The issue can be fixed by modifying the message type detection loop to consider all attachments until it finds a supported media/document type.

Guidance

  • Review the loop at gateway/platforms/discord.py:3264-3285 and adjust it to only break after selecting a supported type.
  • Add a regression test near tests/gateway/test_discord_document_handling.py::test_image_attachment_unaffected for [unsupported, image] ordering to ensure the fix works as expected.
  • Consider prioritizing supported media across the full attachment list to handle cases with multiple attachments.
  • Verify that the event type is correctly derived from the successfully cached media_types/media_urls when a leading unsupported attachment is present.

Example

No code snippet is provided as the issue does not contain enough information to generate a specific code fix.

Notes

The suggested fix may require additional changes to handle edge cases, such as multiple supported attachments or attachments with unknown content types.

Recommendation

Apply a workaround by adjusting the loop at gateway/platforms/discord.py:3264-3285 to consider all attachments until it finds a supported media/document type, as this is the most direct way to address the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Attachment type detection should consider all attachments until it finds a supported media/document type, or derive the final event type from the successfully cached media_types/media_urls. A leading unsupported attachment should not cause a later supported image/audio/video/document to be treated as plain text.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING