Skip to content

Slack: download-file results can leak into auto-reply media and duplicate final text #86300

@shannon0430

Description

@shannon0430

Summary

A Slack thread reply can be delivered multiple times after an agent uses the Slack message tool with action="download-file" on inbound attachments.

The issue appears to be a read/write media boundary problem: media returned by a read-only download/intake action can later be treated as outbound reply media, and the final text/media dedupe does not collapse the text-only fallback when media is present.

Security / privacy note

This report is intentionally sanitized:

  • no workspace names
  • no channel IDs or thread IDs
  • no Slack file IDs
  • no customer/user names
  • no filenames from the original incident
  • no message contents from the original incident
  • no private URLs, tokens, logs, or screenshots

The observed behavior re-uploaded inbound private attachments back into the same Slack thread. I have not confirmed cross-channel or cross-workspace disclosure, but this is still privacy-sensitive because files downloaded for analysis should never become outbound attachments unless explicitly requested by the agent/user.

If maintainers prefer private handling for this class of issue, this can be moved to the repository's private security-reporting flow; the public issue should remain limited to sanitized reproduction details.

Impact

  • Users can see duplicate Slack replies from the same assistant turn.
  • Inbound private files can be re-uploaded back to the thread even though the agent only requested them for local analysis.
  • The duplicate may affect any channel that shares the common auto-reply media merge/delivery pipeline, though the observed reproduction is Slack.

Observed environment

  • OpenClaw: 2026.5.22 (a374c3a)
  • Channel: Slack thread reply
  • Trigger shape: user posted one or more attachments, the agent called message.download-file for analysis, then produced a normal final text response.

Sanitized reproduction outline

  1. In a Slack thread, send a user message with one or more private file attachments.
  2. Agent calls message({ action: "download-file", fileId: "<redacted>" }) to read the attachment.
  3. Agent produces a normal final answer without an explicit MEDIA: directive and without asking to upload the downloaded files.
  4. Observe Slack delivery.

Expected:

  • exactly one final reply containing the final answer text
  • no re-upload of inbound/downloaded files unless the agent explicitly sends/uploads them

Actual:

  • final answer text can be posted twice via different delivery paths
  • downloaded files can be uploaded back into the Slack thread, including file-only messages

Suspected cause

message.download-file returns a result shaped like media metadata/local file access. The auto-reply/final-delivery layer appears to merge tool-result media into outbound reply payloads, even when the tool action was read-only intake.

There is also a dedupe gap: text-only duplicate filtering appears to keep media-bearing payloads before checking duplicate text, so a media-bearing final payload and a text-only final payload with the same text can both be allowed through.

Proposed fix

  1. Mark download-file outputs as non-outbound/read-only media, or strip them from auto-reply payload assembly.
  2. Only explicit outbound intents should attach media:
    • MEDIA: directives
    • message.send / message.upload-file
    • generated media completion events that are explicitly delivery-scoped
  3. Add same-turn final-answer dedupe across media and text-only routes:
    • if media-bearing and text-only payloads share the same normalized final text/signature, send only one user-visible text body
    • file-only messages should not be emitted from read-only tool results
  4. Add a regression test covering Slack download-file followed by a plain final text answer.

Notes

This is not a model double-generation issue: the session had a single final answer. The duplicate appears at delivery time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions