hermes - ✅(Solved) Fix Telegram text delivery works, file attachments report success but never arrive [4 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#13356Fetched 2026-04-22 08:06:53
View on GitHub
Comments
2
Participants
3
Timeline
14
Reactions
0
Author
Timeline (top)
cross-referenced ×4labeled ×4commented ×2referenced ×2

On Hermes Agent v0.10.0, Telegram text messages are delivered successfully, but file attachments are not actually delivered, even though Hermes reports success and returns a Telegram message ID.

Root Cause

This does not look like a basic Telegram configuration issue because:

  • text delivery works
  • chat_id is correct
  • gateway is running
  • profile config and model config are valid

Fix Action

Fixed

PR fix notes

PR #13387: fix(telegram): log document/video send failures instead of printing to stdout (#13356)

Description (problem / solution / changelog)

Addresses the observability portion of #13356.

TL;DR

TelegramAdapter.send_document and send_video wrote native-send exceptions to stdout via print(...) before falling back to the base adapter. On systemd / Docker / journald-captured gateway deployments stdout isn't captured in the gateway log stream — so operators reporting "Hermes says success, Telegram received nothing" had no visible error to diagnose.

Fix: replace print with logger.error(..., exc_info=True), matching the established pattern in send_voice and send_image_file in the same file.

Root cause

gateway/platforms/telegram.py:

# send_document (line 1777)
except Exception as e:
    print(f"[{self.name}] Failed to send document: {e}")   # ← stdout, invisible
    return await super().send_document(...)                # ← fallback to text
# send_video (line 1808) — same pattern
except Exception as e:
    print(f"[{self.name}] Failed to send video: {e}")
    return await super().send_video(...)

The two adjacent native-send methods in the same file already use the correct pattern:

# send_voice (line 1701)
logger.error(
    "[%s] Failed to send Telegram voice/audio, falling back to base adapter: %s",
    self.name, e, exc_info=True,
)

# send_image_file (line 1738) — identical
logger.error(
    "[%s] Failed to send Telegram local image, falling back to base adapter: %s",
    self.name, e, exc_info=True,
)

Only send_document and send_video drifted to print.

Fix

# send_document
except Exception as e:
    logger.error(
        "[%s] Failed to send Telegram document, falling back to base adapter: %s",
        self.name, e, exc_info=True,
    )
    return await super().send_document(chat_id, file_path, caption, file_name, reply_to)

Identical change for send_video. 4 production-line delta total.

Behaviour matrix

ScenarioBeforeAfter
Native send fails → text fallback succeedsprint to stdout (invisible in journald), fallback returns successlogger.error(exc_info=True) to gateway log, fallback returns success
Native send fails → fallback also failsprint to stdout, exception propagateslogger.error(exc_info=True), exception propagates
Native send succeedsunchangedunchanged

Narrow scope — explicitly not changed

  • Fallback routing. Still falls through to super().send_document(...) / super().send_video(...), matching send_voice / send_image_file. This PR only fixes observability.
  • Return value. SendResult still reflects the text fallback's success, same as the sibling methods.
  • Other adapters. Only Telegram had the print pattern; other platforms already use logger.
  • The deeper reporter question — whether Telegram's native send returning a Message object (with message_id) for a subsequently-dropped file is also a bug — is out of scope here. With proper logging in place operators can now diagnose the actual upstream error and decide if that semantic needs changing.

Regression coverage

tests/gateway/test_telegram_documents.py gets 5 new cases (3 for send_document, 2 for send_video), leveraging caplog + capsys:

TestSendDocument:

  • test_send_document_api_error_is_logged_with_exc_info — asserts an ERROR record lands in gateway.platforms.telegram logger with (1) exc_info attached, (2) exception text present, (3) adapter name in message.
  • test_send_document_logs_do_not_hit_stdout — structural pin: the old "[Telegram] Failed to send document" string must not appear on stdout. Prevents regression back to print.
  • test_send_document_still_invokes_base_fallback_on_error — preserved-behaviour canary: this PR only changes observability, not routing.

TestSendVideo: matching pair (..._is_logged_with_exc_info, ..._logs_do_not_hit_stdout).

4 of 4 stdout-and-logger tests fail on clean origin/main (6fb69229) with the exact symptom:

AssertionError: '[Telegram] Failed to send document' is contained here:
  [Telegram] Failed to send document: boom
AssertionError: Expected an ERROR-level log from gateway.platforms.telegram
  on send_document failure

Validation

source venv/bin/activate
python -m pytest tests/gateway/test_telegram_documents.py -q
# 36 passed

Broader Telegram suite (4 test files) → 68 passed, 0 regressions.

Pre-empted review questions

Q. Why not also remove the super() text fallback — isn't returning success=True misleading when the file didn't actually send? Maybe, but that's a deliberate scope-narrowing choice. The same "fall through to base on native failure" pattern exists in send_voice and send_image_file — changing it for Telegram specifically would break adapter symmetry and risk regressions in callers that rely on the fallback. Happy to follow up with a separate PR if the maintainer wants that behavior for Telegram.

Q. Why test both caplog and capsys? caplog pins the positive invariant (error IS logged correctly). capsys pins the negative invariant (error is NOT leaked to stdout). Together they're a two-sided guard — a future refactor that adds print back in addition to logger.error would still be caught by capsys.

Q. Is this a complete fix for #13356? For the observability portion, yes. For the reporter's deeper "success reported, file never arrives" concern, the fix here at minimum makes any raised exception diagnosable. If Telegram is returning message_id for a file that's subsequently server-side dropped, that's either a python-telegram-bot semantics issue or a message_thread_id / path-access issue that needs separate investigation — with proper logging in place operators can now surface the actual upstream error.


<sub>Co-authored via LLM assistance; I've reviewed every line and am responsible for correctness.</sub>

Changed files

  • gateway/platforms/telegram.py (modified, +23/-2)
  • tests/gateway/test_telegram_documents.py (modified, +167/-0)

PR #13421: fix(telegram): ensure file attachments are actually delivered (fixes #13356)

Description (problem / solution / changelog)

Problem

Telegram text delivery works, but file attachments report success but never arrive (#13356).

Root Cause

TelegramAdapter.send_document() caught exceptions and fell back to super().send_document() which sends text like '📎 File: {path}' - this produced a real message ID but never delivered the actual file.

Fix

  • Removed fallback to text delivery in send_document, send_voice, send_image_file, send_video
  • Added validation for msg.message_id in all media send methods
  • send_message_tool._send_telegram() now validates that media send returns valid message_id
  • Returns SendResult(success=False, error=...) on any exception instead of falling back to text

Testing

  • Syntax validation passed
  • Regression tests added for file send failure handling

Files Changed

  • gateway/platforms/telegram.py
  • tools/send_message_tool.py
  • tests/tools/test_telegram_file_fix.py

Changed files

  • gateway/platforms/telegram.py (modified, +851/-295)
  • tests/tools/test_telegram_file_fix.py (added, +164/-0)
  • tools/send_message_tool.py (modified, +550/-111)

PR #13434: fix(telegram): ensure file attachments are actually delivered (fixes #13356)

Description (problem / solution / changelog)

Problem

Telegram text delivery works, but file attachments report success but never arrive (#13356).

Root Cause

TelegramAdapter.send_document() caught exceptions and fell back to super().send_document() which sends text like '📎 File: {path}' - this produced a real message ID but never delivered the actual file.

Fix

  • Removed fallback to text delivery in send_document, send_voice, send_image_file, send_video
  • Added validation for msg.message_id in all media send methods
  • send_message_tool._send_telegram() now validates that media send returns valid message_id
  • Returns SendResult(success=False, error=...) on any exception instead of falling back to text

Testing

  • Syntax validation passed
  • Regression tests added for file send failure handling

Files Changed

  • gateway/platforms/telegram.py
  • tools/send_message_tool.py
  • tests/tools/test_telegram_file_fix.py

Changed files

  • gateway/platforms/telegram.py (modified, +899/-304)
  • tests/tools/test_telegram_file_fix.py (added, +164/-0)
  • tools/send_message_tool.py (modified, +611/-120)

PR #13440: fix(telegram): ensure file attachments are actually delivered (fixes #13356)

Description (problem / solution / changelog)

Problem

Telegram text delivery works, but file attachments report success but never arrive (#13356).

Root Cause

TelegramAdapter.send_document() caught exceptions and fell back to super().send_document() which sends text like '📎 File: {path}' - this produced a real message ID but never delivered the actual file.

Fix

  • Removed fallback to text delivery in send_document, send_voice, send_image_file, send_video
  • Added validation for msg.message_id in all media send methods
  • send_message_tool._send_telegram() now validates that media send returns valid message_id
  • Returns SendResult(success=False, error=...) on any exception instead of falling back to text

Testing

  • Syntax validation passed
  • Regression tests added for file send failure handling

Files Changed

  • gateway/platforms/telegram.py
  • tools/send_message_tool.py
  • tests/tools/test_telegram_file_fix.py

Changed files

  • gateway/platforms/telegram.py (modified, +899/-304)
  • tests/tools/test_telegram_file_fix.py (added, +164/-0)
  • tools/send_message_tool.py (modified, +611/-120)

Code Example

hermes profile use research
   hermes chat
RAW_BUFFERClick to expand / collapse

Summary

On Hermes Agent v0.10.0, Telegram text messages are delivered successfully, but file attachments are not actually delivered, even though Hermes reports success and returns a Telegram message ID.

Environment

  • Hermes Agent: v0.10.0
  • Platform: Telegram direct message
  • Profile: research
  • Gateway: profile-level gateway running
  • OS: Linux
  • Model/provider config is valid, text chat works normally

Observed behavior

Works

  • Sending plain text messages to Telegram works correctly

Fails

  • Sending file attachments does not reach Telegram
  • Hermes still reports success, for example:
    • chat_id: 2027843809
    • message ID: 686 for .docx
    • message ID: 691 for test.txt

But the Telegram client never receives the file.

Reproduction

  1. Start Hermes with a profile that has Telegram configured and gateway running
  2. Open chat:
    hermes profile use research
    hermes chat
  3. Ask Hermes to send a plain text Telegram message
    Result: delivered successfully
  4. Ask Hermes to create and send a small file like test.txt
    Result: Hermes reports success, Telegram receives nothing
  5. Ask Hermes to send a .docx file
    Result: same, Hermes reports success, Telegram receives nothing

Expected behavior

If Hermes reports a successful Telegram file send, the file should actually appear in the Telegram chat.

Actual behavior

Hermes reports success and returns a Telegram message ID, but no file appears in Telegram.

Notes

This does not look like a basic Telegram configuration issue because:

  • text delivery works
  • chat_id is correct
  • gateway is running
  • profile config and model config are valid

It appears specific to Telegram file/document delivery or success-state reporting after attachment send.

Request

Please check:

  • Telegram document/file upload path
  • whether Hermes is treating a queued or partial send as a successful send
  • whether the returned Telegram message ID is real / confirmed
  • any attachment-specific API handling differences vs plain text

extent analysis

TL;DR

Verify the Telegram document/file upload path and check if Hermes is correctly handling attachment-specific API differences for file sends.

Guidance

  • Investigate the Telegram API documentation to ensure Hermes is using the correct endpoint and parameters for sending file attachments.
  • Check the Hermes code for any differences in handling file attachments versus plain text messages, particularly in regards to success state reporting and message ID generation.
  • Review the Telegram message ID returned by Hermes to confirm it matches the expected format and is not being generated prematurely.
  • Test sending file attachments with different types and sizes to see if the issue is specific to certain file types or sizes.

Example

No code snippet is provided as the issue does not include specific code references.

Notes

The issue seems to be specific to Telegram file/document delivery, and the fact that text delivery works suggests that the basic configuration is correct. However, without more information about the Hermes implementation, it's difficult to provide a definitive solution.

Recommendation

Apply a workaround by modifying the Hermes code to handle file attachments separately from plain text messages, ensuring that the Telegram API is called correctly for file uploads and that success states are reported accurately. This is recommended because the issue appears to be related to the specific handling of file attachments in Hermes.

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

If Hermes reports a successful Telegram file send, the file should actually appear in the Telegram chat.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING