Skip to content

fix: JSON-encode object fields in multipart request bodies - #337

Merged
oliverlaz merged 1 commit into
mainfrom
fix/multipart-form-field-encoding
Aug 21, 2026
Merged

fix: JSON-encode object fields in multipart request bodies#337
oliverlaz merged 1 commit into
mainfrom
fix/multipart-form-field-encoding

Conversation

@oliverlaz

Copy link
Copy Markdown
Member

ApiClient built its multipart body with a bare FormData.append(key, value), so any non-file field was coerced by String(). A File survives that, an object does not.

StreamClient.uploadFile/uploadImage worked around it by hand-stringifying user and upload_sizes behind @ts-expect-error. The channel-scoped uploads — chat.uploadChannelFile, chat.uploadChannelImage, channel.uploadChannelFile, channel.uploadChannelImage — had no such wrapper and were broken outright. Verified against the API:

Error: Stream error code 4: UploadChannelFile failed with error: "bad user id"

That's the server reading "[object Object]" as the user id.

Encoding now lives in ApiClient.multipartBodyStringify: files pass through as Blobs, scalars keep their existing coercion, objects and arrays get JSON.stringify, and no-value fields are dropped instead of being sent as the string "undefined" (which the patched global path was also doing). With one encoding site the StreamClient workarounds are redundant and were removed; the overrides stay because the spec still types file as string.

Testing

New __tests__/multipart.test.ts asserts on the FormData that actually reaches fetch — object/array/file/scalar/no-value fields, no double-encoding of pre-encoded strings, plus all four upload entry points. Runs in CI without credentials. Each new-behavior test was confirmed to fail before the fix.

Also added a channel-upload suite to __tests__/file-uploads.test.ts, which had no coverage — this is why the bug shipped. Both suites in that file stay describe.skip per the existing convention there; run live, all 4 pass with the fix and the 2 channel tests fail without it.

Channel uploads sent `user` as the literal string "[object Object]",
which the API rejects with `bad user id`, and fields with no value went
out as the string "undefined". Encode form fields in ApiClient so every
multipart endpoint is covered, rather than only the two global upload
methods StreamClient was hand-patching.
@oliverlaz
oliverlaz requested a review from szuperaz as a code owner August 21, 2026 14:54
@oliverlaz
oliverlaz merged commit 5ed3f5b into main Aug 21, 2026
10 checks passed
@oliverlaz
oliverlaz deleted the fix/multipart-form-field-encoding branch August 21, 2026 14:59
oliverlaz pushed a commit that referenced this pull request Aug 21, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.8.2](v0.8.1...v0.8.2)
(2026-08-21)


### Features

* feed counts endpoint
([#335](#335))
([cd55e36](cd55e36))


### Bug Fixes

* JSON-encode object fields in multipart request bodies
([#337](#337))
([5ed3f5b](5ed3f5b))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants