Accept string bodies for octet-stream uploads#1213
Conversation
A plain string `body` was being rejected for octet-stream operations with "request body must be bytes; provide bodyBase64", which broke existing callers (such as the Microsoft Graph drive item content upload) that send text content as a string. The request layer already handles a string body, so let it through as UTF-8 bytes. Binary uploads still use bodyBase64.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | 612f03e | Jun 29 2026, 06:11 PM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 612f03e | Commit Preview URL Branch Preview URL |
Jun 29 2026, 06:10 PM |
Greptile SummaryThis patch restores the pre-
Confidence Score: 5/5Safe to merge — the change is a one-line relaxation of a validation guard that restores a previously working call path without touching any other body type or request flow. The guard change is minimal and directly matches what No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[invoke: bodyValue resolved] --> B{isOctetStream?}
B -- No --> C[other content-type path]
B -- Yes --> D{typeof bodyValue === 'string'?}
D -- Yes --> E[✅ pass through to applyRequestBody]
D -- No --> F{toUint8Array != null?}
F -- Yes --> E
F -- No --> G[❌ OpenApiInvocationError: provide bodyBase64]
E --> H[applyRequestBody]
H --> I{string?}
I -- Yes --> J[bodyText — UTF-8 bytes on wire]
I -- No --> K{bytes?}
K -- Yes --> L[bodyUint8Array]
K -- No --> M[JSON.stringify fallback — dead code under guard]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[invoke: bodyValue resolved] --> B{isOctetStream?}
B -- No --> C[other content-type path]
B -- Yes --> D{typeof bodyValue === 'string'?}
D -- Yes --> E[✅ pass through to applyRequestBody]
D -- No --> F{toUint8Array != null?}
F -- Yes --> E
F -- No --> G[❌ OpenApiInvocationError: provide bodyBase64]
E --> H[applyRequestBody]
H --> I{string?}
I -- Yes --> J[bodyText — UTF-8 bytes on wire]
I -- No --> K{bytes?}
K -- Yes --> L[bodyUint8Array]
K -- No --> M[JSON.stringify fallback — dead code under guard]
Reviews (1): Last reviewed commit: "fix(openapi): accept a string body for o..." | Re-trigger Greptile |
Cloudflare previewTorn down — the PR is closed. |
What
Octet-stream operations were rejecting a plain string
bodywithapplication/octet-stream request body must be bytes; provide bodyBase64. This broke uploads that pass text content as a string, like the Microsoft Graph drive item content update (drivesUpdateItemsContent).Why
The
bodyBase64work (#1137) added a strict guard that throws whenever an octet-stream body isn't already bytes. ButapplyRequestBodyhas always handled a string body for octet-stream (it sends it as-is), so the guard rejected a shape the request layer was happy to send. Callers passing string content started failing once that path shipped.Fix
Only reject when the body is neither bytes nor a string. A string
bodygoes through as UTF-8 bytes (the long-standing behavior); genuinely binary content still usesbodyBase64, and an object body is still rejected.Updated the octet-stream test that asserted the old "string body fails" behavior to assert it now passes through as UTF-8 bytes. Full
non-json-bodysuite passes (28 tests).