Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Slack By James Joyner IV · · 8 min read Last reviewed Jul 2026

Slack Error Guide: 'too_many_attachments' — Fix Overloaded Messages

Quick answer

Fix the Slack too_many_attachments error: stay under the 100-attachment cap, move to Block Kit blocks, summarize large output, and thread details in chunks.

  • #slack
  • #api
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this Slack error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

The too_many_attachments error is returned by chat.postMessage (and chat.update) when a single message includes more than the maximum number of legacy attachments Slack allows — 100 per message. It is most common in DevOps tooling that maps each item in a list (failing tests, changed files, scan findings, hosts) to one attachment and posts them all in a single message. The fix is either to cap and paginate the items, or — better — to move off legacy attachments to Block Kit blocks, which are the modern, richer surface.

Slack returns HTTP 200 with ok:false:

{
    "ok": false,
    "error": "too_many_attachments"
}

It occurs whenever the attachments array exceeds 100 entries in one API call.

Symptoms

  • chat.postMessage fails only for large result sets (small ones succeed).
  • A report that “usually works” breaks after a big deploy or a noisy scan.
  • One-attachment-per-item loops that grow unbounded with input size.
  • The same code works until the underlying list crosses ~100 items.

Common Root Causes

1. One attachment per list item

Building attachments by appending an entry for every finding/test/host, with no cap, eventually exceeds 100.

2. Aggregating many sources into one message

Merging results from multiple jobs into a single message multiplies attachment count.

3. Legacy attachments instead of blocks

Sticking with the deprecated attachments field keeps you under its 100-item ceiling; blocks is the modern path with a higher, more flexible limit (up to 50 blocks per message, richer layout).

4. No pagination or truncation

Unbounded output with no “and N more…” summarization.

Diagnostic Workflow

Step 1: Reproduce with an oversized attachments array

# Build 101 trivial attachments and post them
ATT=$(python3 -c 'import json; print(json.dumps([{"text": f"item {i}"} for i in range(101)]))')
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d "{\"channel\":\"C0123456789\",\"attachments\":$ATT}" | jq .error
"too_many_attachments"

Step 2: Count attachments before sending

echo "$ATT" | jq 'length'
101

Any count over 100 will be rejected — validate this client-side before the call.

Step 3: Cap the list and add a summary

# Keep the first 95 and append a summary line for the rest
CAPPED=$(echo "$ATT" | jq '.[:95] + [{"text":"…and 6 more (truncated)"}]')
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d "{\"channel\":\"C0123456789\",\"attachments\":$CAPPED}" | jq '{ok}'
{
  "ok": true
}

Step 4: Prefer Block Kit blocks

curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d '{
        "channel":"C0123456789",
        "blocks":[
          {"type":"header","text":{"type":"plain_text","text":"Scan results"}},
          {"type":"section","text":{"type":"mrkdwn","text":"*12* findings — see thread for details"}}
        ]
      }' | jq '{ok, ts}'
{
  "ok": true,
  "ts": "1720526400.001900"
}

Post the summary as blocks, then push details into the thread.

Example Root Cause Analysis

A CI bot posts one attachment per failing test. A large regression run produces 140 failures and the notification never appears:

curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d "{\"channel\":\"C0123456789\",\"attachments\":$FAILING_TESTS}" | jq .error
"too_many_attachments"

The bot maps every failing test to an attachment with no ceiling, so 140 tests exceed the 100 cap. The fix is to post a summary block with the count, attach only the top offenders, and thread the full list in chunks:

# 1) Summary message
TS=$(curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d '{"channel":"C0123456789","text":":x: 140 tests failed — details in thread"}' | jq -r '.ts')

# 2) Threaded chunks of <=100
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d "{\"channel\":\"C0123456789\",\"thread_ts\":\"$TS\",\"attachments\":$FIRST_100}" | jq .ok
true

Summarizing in the root message and threading capped chunks keeps every call under the limit and the channel readable.

Prevention Best Practices

  • Validate attachments.length <= 100 (and blocks.length <= 50) client-side before posting.
  • Migrate from legacy attachments to Block Kit blocks for richer, better-supported layouts.
  • Summarize large result sets (“N findings”) in the root message and thread the details in capped chunks.
  • Truncate with an explicit “…and N more” and a link to the full report rather than dumping everything inline.
  • Paginate long output across threaded replies instead of one giant message.
  • For ad-hoc triage, the free incident assistant can help restructure an oversized report into a summary + thread. See more in Slack guides.

Quick Command Reference

# Count attachments before sending
echo "$ATT" | jq 'length'

# Cap to 95 + a truncation note
echo "$ATT" | jq '.[:95] + [{"text":"…and more (truncated)"}]'

# Post a Block Kit summary instead of many attachments
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d '{"channel":"C0123456789","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"*12* findings"}}]}' | jq .ok

Conclusion

too_many_attachments means a single message exceeded the 100 legacy-attachment cap. The usual root causes:

  1. One attachment per list item with no ceiling.
  2. Merging many sources into one message.
  3. Staying on legacy attachments instead of blocks.
  4. No pagination or truncation of large output.

Cap the array below 100, prefer Block Kit blocks, summarize the count in the root message, and thread the details in chunks.

Free download · 368-page PDF

Fixed it? Get 500 Slack & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.