hermes - ✅(Solved) Fix [Bug]: MEDIA: tags with Windows paths not parsed — images sent as plain text [1 pull requests, 2 comments, 3 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#28989Fetched 2026-05-20 04:00:44
View on GitHub
Comments
2
Participants
3
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×3commented ×2cross-referenced ×1

The extract_media() function in gateway/platforms/base.py uses a regex that only matches Unix-style paths (~/ or /). Windows paths like C:/Users/.../image.jpg or C:\\Users\\...\\image.jpg are not recognized, so MEDIA: tags are not extracted and the raw path text is sent to messaging platforms instead of the actual image.

This is a root cause of issue #6249 and related media delivery failures on Windows.

Root Cause

In gateway/platforms/base.py, line ~2162:

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/)\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)

The path matching group (?:~/|/) only matches:

  • ~/ (Unix home directory)
  • / (Unix absolute path)

It does NOT match:

  • C:/ or C:\\ (Windows drive letters)
  • D:/, E:/, etc.

Fix Action

Fix

Change the path matching group from (?:~/|/) to (?:~/|/|[A-Za-z]:[/\\]):

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/|[A-Za-z]:[/\\])\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)

This adds support for Windows drive letters with both forward and backward slashes.

PR fix notes

PR #28991: fix(gateway): recognize Windows drive-letter paths in extract_local_files() bare-path uploads

Description (problem / solution / changelog)

What does this PR do?

gateway.platforms.base.BasePlatformAdapter.extract_local_files() anchors its bare-path regex on (?:~/|/), which only matches Unix absolute/home paths. Windows drive-letter paths (C:/Users/..., C:\\Users\\..., D:/..., etc.) silently fail to match, so the gateway never recognizes them as native uploads and the raw text is sent through to the messaging platform instead.

The fix widens the path anchor to (?:~/|/|[A-Za-z]:[/\\]) and allows \\ as an in-path separator. A (?<![/:\w.]) negative lookbehind is already present so URLs and relative paths (./foo.png) continue to be rejected.

Audited siblings: extract_media() in the same file has the same Unix-only anchor, but @liuhao1024 already covered it in #24049 (plus GIS extension additions). After @alt-glitch's partial-overlap flag I reverted the extract_media() half of this PR so the two PRs no longer compete on the same surface — this PR is now scoped to the parallel extract_local_files() bug only.

Related Issue

Discovered while reviewing #28989 (which reports the extract_media() half). This PR does not close #28989 — #24049 is the canonical fix there.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • gateway/platforms/base.py — widen the extract_local_files() path anchor to accept [A-Za-z]:[/\\] drive-letter prefixes and \\ as an in-path separator.
  • tests/gateway/test_extract_local_files.py — replace the now-obsolete test_windows_path_not_matched assertion with a parametrized positive test across four drive-letter shapes (uppercase C:, lowercase e:, forward and back slashes, non-C: drive) plus a regression guard confirming a bare relative foo\\bar.png still does NOT match.

How to Test

  1. Reproduce the bug on origin/main:
    uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest tests/gateway/test_extract_local_files.py::TestEdgeCases::test_windows_drive_letter_paths_matched -v
    → fails (anchor doesn't match Windows paths).
  2. Apply this PR and rerun the same command → 4/4 pass.
  3. Full file regression: uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest tests/gateway/test_extract_local_files.py -v → 48 passed locally.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run focused tests for the touched code and all pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15.x

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A (the function-level comment above the regex is updated to describe the new anchor)
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) — this IS the cross-platform fix; the new regex is OS-neutral
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Related / Positioning

  • #24049 (@liuhao1024) — covers extract_media() Windows-path anchor + GIS extensions. Canonical fix for #28989. No overlap with this PR after the narrowing in $SHA.
  • #24384 (@Kyzcreig) — extract_media() prefix-glue, space-truncation, and allowlist narrowing. Orthogonal to this PR.
  • #20843 (@liuhao1024) — removes the extract_local_files() CALL from _deliver_media_from_response(). If that PR lands first, this PR becomes a defense-in-depth improvement to the function for callers that still invoke it directly.

CI failures on this PR are pre-existing baselines on origin/main (test_restart_resume_pending, test_anthropic_error_handling 429/500 timeouts, test_file_operations missing _check_git_baseline, etc.) — none touch gateway/platforms/base.py or the extract_local_files test file.

Changed files

  • gateway/platforms/base.py (modified, +3/-2)
  • tests/gateway/test_extract_local_files.py (modified, +29/-3)

Code Example

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/)\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)

---

send_message_tool({
    "action": "send",
    "target": "telegram:CHAT_ID",
    "message": "MEDIA:C:/Users/gizmo/image.jpg"
})

---

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/|[A-Za-z]:[/\\])\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)
RAW_BUFFERClick to expand / collapse

[Bug]: MEDIA: tags with Windows paths are not parsed, causing images to be sent as plain text

Summary

The extract_media() function in gateway/platforms/base.py uses a regex that only matches Unix-style paths (~/ or /). Windows paths like C:/Users/.../image.jpg or C:\\Users\\...\\image.jpg are not recognized, so MEDIA: tags are not extracted and the raw path text is sent to messaging platforms instead of the actual image.

This is a root cause of issue #6249 and related media delivery failures on Windows.

Environment

  • OS: Windows 10/11
  • Hermes version: 0.14.0
  • Affected platforms: All messaging platforms (Telegram, Discord, Slack, etc.)

Root Cause

In gateway/platforms/base.py, line ~2162:

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/)\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)

The path matching group (?:~/|/) only matches:

  • ~/ (Unix home directory)
  • / (Unix absolute path)

It does NOT match:

  • C:/ or C:\\ (Windows drive letters)
  • D:/, E:/, etc.

Reproduction

On Windows, call send_message with a Windows path:

send_message_tool({
    "action": "send",
    "target": "telegram:CHAT_ID",
    "message": "MEDIA:C:/Users/gizmo/image.jpg"
})

Expected: Image is uploaded as native attachment. Actual: The text MEDIA:C:/Users/gizmo/image.jpg is sent as a plain message.

Fix

Change the path matching group from (?:~/|/) to (?:~/|/|[A-Za-z]:[/\\]):

media_pattern = re.compile(
    r'''[`"']?MEDIA:\s*(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|(?:~/|/|[A-Za-z]:[/\\])\S+(?:[^\S\n]+\S+)*?\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa)(?=[\s`"',;:)\]}]|$))[`"']?'''
)

This adds support for Windows drive letters with both forward and backward slashes.

Related Issues

  • #6249 — Telegram MEDIA image delivery echoes local file path (same symptom, different proposed fix)
  • #19105 — WhatsApp media delivery fails (may be partially related)

Type of Change

  • 🐛 Bug fix

Files Changed

  • gateway/platforms/base.py — 1 line changed in regex pattern

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug]: MEDIA: tags with Windows paths not parsed — images sent as plain text [1 pull requests, 2 comments, 3 participants]