zed-industries/zed · error · RuntimeError
Slack webhook returned {response.status_code}: {response.tex
Error message
Slack webhook returned {response.status_code}: {response.text[:200]} What it means
The incoming-webhook POST returned a status other than 200 and the script raises with the code plus the first 200 characters of the body, which identify the cause: 400 invalid_payload, 404/410 deleted webhook or uninstalled app, 403 wrong workspace, 429 rate limited, 5xx Slack-side incident. There is no retry, so a single blip or an over-long message kills the notification.
Source
Thrown at script/github-guild-board.py:411
# without every caller having to remember to do it.
return f"<{url}|{escape_slack(text)}>"
def send_slack(text):
webhook = os.environ.get("SLACK_WEBHOOK_GUILD_INTERNAL")
if not webhook:
raise RuntimeError("SLACK_WEBHOOK_GUILD_INTERNAL is not set")
message = f"{random.choice(ZEDGAR_QUIPS)} {text}"
response = requests.post(
webhook,
json={
"text": message,
"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": message}}],
},
timeout=30,
)
if response.status_code != 200:
raise RuntimeError(
f"Slack webhook returned {response.status_code}: {response.text[:200]}"
)
def parse_dt(value):
return datetime.fromisoformat(value.replace("Z", "+00:00"))
def item_status(item):
for field_value in (item.get("fieldValues") or {}).get("nodes", []):
if field_value.get("field", {}).get("name") == STATUS_FIELD:
return field_value.get("name")
return None
def latest_check_in_time(comments):
times = [
parse_dt(comment["created_at"])View on GitHub (pinned to bc538def45)
Solutions
- Read the body snippet in the message: 'invalid_payload' means trim or split the blocks; 'no_team_found'/404 means recreate the webhook
- Truncate each Slack text block to the 3000-char limit before sending
- On 429 or 5xx, honor Retry-After and retry once or twice instead of failing the run
- If the webhook is dead, create a new one and update the CI secret
Example fix
// before
if response.status_code != 200:
raise RuntimeError(f"Slack webhook returned {response.status_code}: {response.text[:200]}")
// after
for attempt in range(3):
if response.status_code == 200:
break
if response.status_code in (429, 500, 502, 503) and attempt < 2:
time.sleep(int(response.headers.get("Retry-After", "2")))
response = requests.post(webhook, json=payload, timeout=30)
continue
raise RuntimeError(f"Slack webhook returned {response.status_code}: {response.text[:200]}") Defensive patterns
Strategy: retry
Validate before calling
def slack_blocks_within_limits(blocks: list) -> bool:
return all(
len(b.get("text", {}).get("text", "")) <= 3000
for b in blocks
if b.get("type") == "section"
) Type guard
def slack_post_succeeded(response) -> bool:
return response.status_code == 200 Try / catch
try:
send_slack(summary)
except RuntimeError as exc:
status = exc.split(' ')[3] if ' ' in exc else ''
if ' 429' in str(exc) or ' 5' in str(exc):
time.sleep(5)
send_slack(summary)
else:
raise Prevention
- Truncate Slack text blocks to 3000 chars before posting
- Honor Retry-After on 429 responses
- Recreate webhooks promptly when apps/channels change and update the secret
- Keep notifications idempotent so retries do not double-post
When it happens
Trigger: POST to the hooks.slack.com URL with a mrkdwn block exceeding Slack's 3000-char text limit returns 400 invalid_payload; the webhook was deleted or its app uninstalled returns 404/410; bursts faster than roughly one message per second return 429; Slack incidents return 5xx.
Common situations: Guild board summaries growing past block limits as the team grows; channel/webhook removed during a workspace reorg; CI retries spamming the webhook; incoming-webhook app uninstalled for a newer integration.
Related errors
- GraphQL failed after {retries} retries: {last_err}
- GraphQL errors: {json.dumps(data['errors'])[:300]}
- GraphQL error: {result['errors']}
- GraphQL error: {result['errors']}
- SLACK_WEBHOOK_GUILD_INTERNAL is not set
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/4c2d938bc179c56c.
Report an issue: GitHub.