← Back to PRs

#16791: fix(discord): use rawBody with explicit Content-Type for voice message uploads

by Limitless2023 open 2026-02-15 04:07 View on GitHub →
channel: discord stale size: XS
Fixes #16762 ## Problem Discord voice messages fail with HTTP 400 error: Expected Content-Type header to be one of application/json. ## Root Cause When calling rest.post with body containing a files field, Carbon (@buape/carbon) auto-detects it and switches to FormData mode (multipart/form-data). However, Discord /attachments endpoint requires application/json and rejects FormData. ## Solution Use rawBody with pre-serialized JSON and explicit Content-Type: application/json header to bypass Carbon automatic FormData detection. ## Changes - Changed rest.post call to use rawBody instead of body - Added explicit Content-Type: application/json header - Added comment explaining why this is necessary ## Testing This fix ensures Discord voice messages can be sent successfully without HTTP 400 errors. <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes Discord voice message uploads failing with HTTP 400 (`Expected Content-Type header to be one of application/json`). The `/channels/{channelId}/attachments` endpoint expects a JSON body with file metadata (`filename`, `file_size`, `id`), but Carbon's `RequestClient` auto-detects the `files` key in `body` and switches to `multipart/form-data`. The fix uses `rawBody` with `JSON.stringify` and an explicit `Content-Type: application/json` header to bypass Carbon's auto-detection. - Switched from `body` to `rawBody` with pre-serialized JSON for the upload URL request (Step 1) - Added explicit `Content-Type: application/json` header - Added explanatory comment documenting the workaround - Step 3 (message creation) is unaffected since it uses `attachments`, not `files` - The `rawBody` and `headers` options are already used elsewhere in the codebase (`send.guild.ts`), confirming API compatibility <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it's a targeted, well-documented fix for a clear API compatibility issue. - The change is minimal (3 lines of logic + 2 comment lines), addresses a concrete HTTP 400 error with a well-understood root cause, and uses established patterns already present in the codebase (rawBody and headers options). No new dependencies, no behavioral changes beyond fixing the broken endpoint call. - No files require special attention. <sub>Last reviewed commit: ac5f162</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs