slack_read_file returns malformed content block for PDF attachments >= ~5 MB

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 14, 2026

Component: Slack MCP connector — slack_read_file tool

Summary: Reading a binary (PDF) attachment via slack_read_file fails with an MCP schema validation error when the file is roughly 5 MB or larger, even though the tool's documented cap is 10 MB. The same files read successfully when uploaded directly into Claude (not via Slack), which rules out the files themselves being malformed or unparseable.

Steps to reproduce:

  1. In a Slack channel/thread, attach a PDF ≥ ~5 MB.
  2. Call slack_read_file with that file's ID.

Observed:

MCP error -32602: Invalid tools/call result: [...]

The error shows the second content block in the response (path: ["content", 1]) failing validation against all five MCP content-type schemas (text, image, audio, resource_link, resource) simultaneously — each variant's required payload field (text, data, blob, etc.) is undefined. The block carries a type tag but no actual payload, i.e. the response is malformed rather than a clean error.

Reproduced with (both from the same Slack thread):

  • 901_Wicker_St_Residential_Solar_Array_PlanSet_Mon_Aug_3_2026_13-05-52.pdf — 5.5 MB — failed twice
  • 901_WICKER_ST_WOODSTOCK_IL_US_60098.pdf — 5.2 MB — failed twice, including a fresh call with no other change

Expected: Either the file content returns successfully (both files are under the documented 10 MB cap), or the tool returns a clean, schema-valid error (e.g. a text block stating the file is too large) instead of a payload-less block that fails client-side schema validation.

Impact: Any workflow depending on reading Slack-attached PDFs over a few MB (e.g. permit packages, plan sets, contracts) breaks with an opaque schema error rather than an actionable one.

Notes:

  • Retrying the same file, waiting and retrying fresh, and trying the smaller of two files all produced the identical failure — this is deterministic at this size range, not transient.
  • Likely mechanism: the connector's Slack-side file fetch (auth + download + base64-encode) hits an internal size/timeout limit and returns a partially-built content block instead of surfacing a clean error.

View original on GitHub ↗