Skip to content

fix(slack): harden attachment handling#16281

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-aa28dba4
Apr 27, 2026
Merged

fix(slack): harden attachment handling#16281
teknium1 merged 2 commits into
mainfrom
hermes/hermes-aa28dba4

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Consolidates several overlapping Slack attachment bugs that made file handling flaky.

Changes

  1. Upload retry with backoff_upload_file, send_video, send_document now do 3 attempts with 1.5s × attempt backoff on transient errors (429, 5xx, connection reset, rate_limited, service unavailable). New _is_retryable_upload_error helper.
  2. Thread participation tracking — successful uploads now add thread_ts to _bot_message_ts (same mechanism as text replies), so follow-up thread messages auto-trigger the bot instead of being ignored.
  3. Thread metadata preserved in fallbackssend_image's SSRF redirect-guard text fallback and two gateway/run.py send paths (image + document fallback) now pass metadata through, so thread replies land in the right thread.
  4. HTML response rejection in _download_slack_file_bytes — parallels the existing check in _download_slack_file (images/audio). Guards against Slack returning a sign-in/redirect page as document bytes when scopes are missing, so the agent doesn't get HTML-as-PDF cached.
  5. File lifecycle event acksfile_shared / file_created / file_change events now have no-op handlers to silence bolt 'Unhandled request' 404 warnings around snippet uploads.
  6. Post-loop media-type classification — mixed image+document uploads now correctly pick PHOTO > VOICE > DOCUMENT instead of being overwritten unpredictably inside the per-file loop.
  7. Expanded text-inject whitelist.csv, .json, .xml, .yaml, .yml, .toml, .ini, .cfg are now injected directly into the prompt (up to 100KB) instead of being cached as opaque uploads. Paired with matching MIME entries in SUPPORTED_DOCUMENT_TYPES (base.py).

Validation

tests/gateway/test_slack.py + test_slack_mention.py + test_slack_approval_buttons.py + test_media_download_retry.py + test_session.py + test_channel_directory.py: 354 passed.

Credits

  • fix: harden Slack attachment handling #11819 by @ghostmfr — salvaged as 10972ac with authorship rewritten to the GitHub noreply email (original commits used a local-dev hostname, which would have broken release-notes attribution). Two PR commits squashed into one so the single commit carries contributor credit.

Closes #11819

ghostmfr and others added 2 commits April 26, 2026 18:16
Multiple overlapping Slack attachment improvements:

1. Upload retry with backoff on transient errors (429, 5xx, connection
   reset, rate_limited, service unavailable). New _is_retryable_upload_error
   helper covers three upload paths: _upload_file, send_video,
   send_document. Up to 3 attempts with 1.5s * attempt backoff.

2. Thread participation tracking: successful file uploads now add the
   thread_ts to _bot_message_ts, mirroring how text replies are tracked.
   This lets follow-up thread messages auto-trigger the bot (same
   engagement rules as replied threads).

3. Thread metadata preservation in the image redirect-guard fallback
   (send_image → send text fallback) and in two gateway.run.py send
   paths (image + document fallback calls).

4. HTML response rejection in _download_slack_file_bytes. Parallels
   the existing check in _download_slack_file. Guards against Slack
   returning a sign-in / redirect page as document bytes when scopes
   are missing, so the agent doesn't get HTML-as-a-PDF.

5. File lifecycle event acks (file_shared / file_created / file_change).
   These events arrive around snippet uploads. Acking them silences the
   slack_bolt 'Unhandled request' 404 warnings without changing behavior.

6. Post-loop message type classification so a mixed image+document upload
   classifies as PHOTO (or VOICE if no image), falling back to DOCUMENT.
   Previously, the per-file classification in the inbound loop could be
   overwritten unpredictably.

7. Expanded text-inject whitelist in inbound document handling to cover
   .csv, .json, .xml, .yaml, .yml, .toml, .ini, .cfg (up to 100KB) so
   snippets and config files are directly visible to the agent, not just
   cached as opaque uploads. Paired with new MIME entries in
   SUPPORTED_DOCUMENT_TYPES in base.py.

Squashed from two commits in #11819 so the single commit carries the
contributor's GitHub attribution (the original commits were authored
under a local dev hostname).
@teknium1 teknium1 merged commit 5db6db8 into main Apr 27, 2026
10 of 11 checks passed
@teknium1 teknium1 deleted the hermes/hermes-aa28dba4 branch April 27, 2026 01:20
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists platform/slack Slack app adapter comp/gateway Gateway runner, session dispatch, delivery labels Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/slack Slack app adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants