From f9885130b42d3b34e0289f91cafed736f67dae97 Mon Sep 17 00:00:00 2001 From: kunlabs <10774721+kunlabs@users.noreply.github.com> Date: Sun, 26 Apr 2026 12:33:57 -0700 Subject: [PATCH] fix(slack): download files in Slack Connect channels Slack Connect channels return file objects with file_access="check_file_info" and no url_private_download field (see https://docs.slack.dev/reference/objects/file-object/#slack_connect_files). These stub objects must be resolved via files.info before download can proceed. Without this the agent silently skips attachments posted in Slack Connect channels. Call files.info on every file whose file_access is check_file_info, replace the stub with the full file object, and let the existing download path continue. Warn and skip on files.info failures. Closes #11095. --- gateway/platforms/slack.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gateway/platforms/slack.py b/gateway/platforms/slack.py index 149b150fd..443f684e4 100644 --- a/gateway/platforms/slack.py +++ b/gateway/platforms/slack.py @@ -1195,6 +1195,29 @@ class SlackAdapter(BasePlatformAdapter): media_types = [] files = event.get("files", []) for f in files: + # Slack Connect channels return stub file objects with + # file_access="check_file_info" and no URL fields. We must + # call files.info to retrieve the full object (including url_private_download) + # before we can download it. + # https://docs.slack.dev/reference/objects/file-object/#slack_connect_files + if f.get("file_access") == "check_file_info": + file_id = f.get("id") + if not file_id: + continue + try: + info_resp = await self._get_client(channel_id).files_info(file=file_id) + if info_resp.get("ok"): + f = info_resp["file"] + else: + logger.warning( + "[Slack] files.info failed for %s: %s", + file_id, info_resp.get("error"), + ) + continue + except Exception as e: + logger.warning("[Slack] files.info error for %s: %s", file_id, e, exc_info=True) + continue + mimetype = f.get("mimetype", "unknown") url = f.get("url_private_download") or f.get("url_private", "") if mimetype.startswith("image/") and url: