Skip to content

Fix Teams 413 error: add charset=utf-8 to Content-Type header and retry on 413#2162

Open
devin-ai-integration[bot] wants to merge 2 commits intomasterfrom
devin/1774046106-fix-teams-413-charset
Open

Fix Teams 413 error: add charset=utf-8 to Content-Type header and retry on 413#2162
devin-ai-integration[bot] wants to merge 2 commits intomasterfrom
devin/1774046106-fix-teams-413-charset

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 20, 2026

Summary

Fixes persistent HTTP 413 (Request Entity Too Large) errors from Microsoft Teams webhooks, even after the payload truncation logic from #2160.

Root cause: The Teams webhook connector converts the request body to UTF-16 when charset is not specified in the Content-Type header, effectively doubling the payload size before enforcing the 28KB limit. A 14KB payload becomes ~28KB after conversion, triggering a 413. (Source)

Changes:

  1. Set Content-Type: application/json; charset=utf-8 so the connector skips the UTF-16 conversion
  2. Added a retry safety net: if Teams still returns a 413 in the response body (old webhook connectors return HTTP 200 with error text), retry once with a minimal card

Review & Testing Checklist for Human

  • Verify the charset=utf-8 fix works with Prendio's specific webhook type (old O365 connector vs new Power Automate workflow webhook — behavior may differ)
  • Check that the "413" in response.text substring match won't false-positive on legitimate response text from Teams
  • Confirm that the retry's _minimal_card(card) fallback produces a payload small enough for Teams in all cases (it uses **card which preserves non-body fields)
  • Trigger or wait for the next Prendio DAG run after deployment and verify alerts are delivered successfully

Notes

  • The charset fix is based on community findings (SO answer), not official Microsoft documentation. It should be monitored after deployment.
  • If the retry also fails with a 413-in-body response, it falls through to the existing error handling in send_message — no behavior regression.
  • No unit tests were added; the fix is best validated by a production run against the Prendio webhook.

Link to Devin session: https://app.devin.ai/sessions/d746de1f2743489995cc5070957c91c6

Summary by CodeRabbit

  • Bug Fixes
    • Improved Teams messaging integration to automatically retry with a compact card format when service responses indicate payload-size issues, increasing delivery reliability.
    • Added request timeouts to avoid long waits and ensured UTF-8 content encoding in outgoing requests for better compatibility.
…ry on 413 Co-Authored-By: Michael Myaskovsky <michael@elementary-data.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring
@github-actions
Copy link
Contributor

👋 @devin-ai-integration[bot]
Thank you for raising your pull request.
Please make sure to add tests and document all user-facing changes.
You can do this by editing the docs files in this pull request.

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba3516b1-3859-4d7c-aa1f-7d02c28bf195

📥 Commits

Reviewing files that changed from the base of the PR and between a715f67 and 49a3dbd.

📒 Files selected for processing (1)
  • elementary/messages/messaging_integrations/teams_webhook.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • elementary/messages/messaging_integrations/teams_webhook.py

📝 Walkthrough

Walkthrough

The Teams webhook handler now sets Content-Type: application/json; charset=utf-8, applies a request timeout, and retries with a minimal AdaptiveCard payload if an HTTP 200 response body contains "413", logging a warning before the retry. (50 words)

Changes

Cohort / File(s) Summary
Teams Webhook Error Handling
elementary/messages/messaging_integrations/teams_webhook.py
Added REQUEST_TIMEOUT_SECONDS and applied timeout to requests.post. Updated Content-Type to include charset=utf-8. Changed _minimal_card to explicitly set "type": "AdaptiveCard" and "version". After a successful initial POST, if response is 200, response body length > 1, and contains "413", log a warning and resend with a minimal-card payload; retry response is returned.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I tapped the webhook, hopeful and bright,
The server sighed "413" in the night,
I trimmed the card, set UTF-8 neat,
I retried with patience — message complete! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main changes: adding charset=utf-8 to Content-Type header and implementing a retry mechanism for 413 errors in Teams webhook integration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1774046106-fix-teams-413-charset

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed. Inline comments: In `@elementary/messages/messaging_integrations/teams_webhook.py`: - Around line 122-123: The retry payload still contains large top-level fields because _minimal_card(card) clones the entire original card and only swaps out body; change _minimal_card to build and return a brand-new minimal dict (do not copy the original) that includes only the small required keys (e.g., card type/summary/title if needed) plus the new body, ensuring any large fields from the original card are omitted before calling _build_payload; update callers using _minimal_card(card) accordingly so payload only contains those minimal keys. - Around line 107-128: The two requests.post calls that send Teams webhooks (the initial call and the retry in the branch that builds a minimal card) lack an explicit timeout and can block indefinitely; update both calls to pass a reasonable timeout value (e.g. timeout=5 or a configured constant) to requests.post so the worker won't hang, and ensure the same timeout constant is used for both the initial send and the retry paths that call _build_payload and _minimal_card. 

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72f4a384-745c-4c03-816c-fd7c00202f35

📥 Commits

Reviewing files that changed from the base of the PR and between ed170b7 and a715f67.

📒 Files selected for processing (1)
  • elementary/messages/messaging_integrations/teams_webhook.py
Co-Authored-By: Michael Myaskovsky <michael@elementary-data.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

0 participants