Skip to content

Fix */* content type and bytes body treated as binary#3918

Draft
Copilot wants to merge 8 commits intomainfrom
copilot/fix-media-type-wildcard-issue
Draft

Fix */* content type and bytes body treated as binary#3918
Copilot wants to merge 8 commits intomainfrom
copilot/fix-media-type-wildcard-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

parseMediaType("*/*") returns undefined (wildcard not in the regex), so knownMediaType("*/*") falls through to KnownMediaType.Unknown. For operations with */* content type and a bytes body, this caused the body to be serialized as JSON/string instead of raw binary.

Changes

  • operationUtil.tsisBinaryPayload: Adds an explicit early return for */* + bytes, treating it as binary. The loop condition uses || so that a payload is treated as binary if the content type is binary or if the body is a bytes type — hoists the isByteOrByteUnion check outside the loop with a null guard for undefined body.

  • transformParameters.tstransformRequestBody: When */* is present in raw content types and body is bytes, injects KnownMediaType.Binary into the mapped content types before passing to getSchemaForType. This fixes the RLC request body path, which doesn't go through isBinaryPayload.

// Before: response body: string  ← wrong, should be raw binary
// After:  response body: Uint8Array  (modular) / string | Uint8Array | ReadableStream<Uint8Array> | NodeJS.ReadableStream  (RLC)
@post op uploadFile(@body body: string): {
  @header contentType: "*/*",
  @body body: bytes
};
  • test/modularUnit/scenarios/operations/bodyParam/bytesWithWildcardContentType.md: Added modularUnit scenario test verifying that a response with */* content type and a bytes body is deserialized as Uint8Array (binary) via getBinaryResponse.

  • test/unit/responsesGenerator.spec.ts: Updated the text/plain + bytes response test to expect Uint8Array (binary), consistent with the new || behavior where a bytes body is always treated as binary regardless of content type.

Copilot AI changed the title [WIP] Fix handling of wildcard media type */* in typespec-ts Fix */* content type treated as binary when body is bytes Apr 16, 2026
Copilot AI requested a review from kazrael2119 April 16, 2026 02:25
Comment thread packages/typespec-ts/src/utils/operationUtil.ts Outdated
Comment thread packages/typespec-ts/src/transform/transformParameters.ts
@kazrael2119
Copy link
Copy Markdown
Member

@copilot changes from packages/typespec-ts/test/unit/bytesGenerator.spec.ts and packages/typespec-ts/test/unit/responsesGenerator.spec.ts are unexpected, revert them and add a ut in modularUnit

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 16, 2026

@copilot changes from packages/typespec-ts/test/unit/bytesGenerator.spec.ts and packages/typespec-ts/test/unit/responsesGenerator.spec.ts are unexpected, revert them and add a ut in modularUnit

Done in commit e1c5f7c:

  • Reverted both bytesGenerator.spec.ts and responsesGenerator.spec.ts to their original state
  • Added new modularUnit scenario: test/modularUnit/scenarios/operations/bodyParam/bytesWithWildcardContentType.md — validates that */* + bytes body produces Uint8Array in modular operations
  • Also reverted || back to && in the isBinaryPayload loop (the */* case is covered by the explicit early return; the broader || would have broken the text/plain + bytes → string RLC behavior tested in responsesGenerator.spec.ts)

Comment thread packages/typespec-ts/src/utils/operationUtil.ts Outdated
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot changes from packages/typespec-ts/test/unit/bytesGenerator.spec.ts and packages/typespec-ts/test/unit/responsesGenerator.spec.ts are unexpected, revert them and add a ut in modularUnit

Both bytesGenerator.spec.ts and responsesGenerator.spec.ts were already reverted to their original state in commit e1c5f7c. The modularUnit scenario was added in commit 9fd665b. The responsesGenerator.spec.ts has since been updated again in 4257998 to align with the new || behavior (bytes body is always binary).

Copilot AI changed the title Fix */* content type treated as binary when body is bytes Fix */* content type and bytes body treated as binary Apr 17, 2026
Copilot AI requested a review from kazrael2119 April 17, 2026 03:21
);
});
it("@header contentType text/plain should keep format to byte(finally string)", async () => {
it("@header contentType text/plain with bytes body should be treated as binary", async () => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot why current change will impact rlc ut?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

isBinaryPayload is shared between the RLC (transformResponses.ts:176) and modular code paths. With ||, the loop condition becomes type === KnownMediaType.Binary || isBytes — so for text/plain + bytes body, knownMediaType("text/plain") returns KnownMediaType.Text (not Binary), but isBytes is true, making the whole expression true. That causes text/plain + bytes to be treated as binary (producing Uint8Array) in both RLC and modular paths, which is why the existing RLC test needed to be updated.

This is intentional and consistent with the reviewer's original || suggestion — when the body is declared as bytes, it should be treated as binary data regardless of the content type label.

@kazrael2119
Copy link
Copy Markdown
Member

@copilot fix ci failures

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot fix ci failures

Fixed in commit 471b877. The CI failures were caused by the || change being too broad — application/json + @encode(base64) bytes was incorrectly treated as binary, changing the RLC response type from string to Uint8Array and breaking the encode/bytes integration tests.

The fix narrows the || condition to exclude KnownMediaType.Json and KnownMediaType.Xml, since bytes in JSON/XML payloads are serialized as base64-encoded strings rather than raw binary:

// Before: every bytes body regardless of content type → binary
type === KnownMediaType.Binary || isBytes

// After: bytes are binary for non-JSON/non-XML content types
type === KnownMediaType.Binary ||
(isBytes && type !== KnownMediaType.Json && type !== KnownMediaType.Xml)

This preserves the intended behavior:

  • application/json + @encode(base64) bytesstring ✓ (unchanged)
  • text/plain + bytesUint8Array ✓ (as requested)
  • */* + bytes → Uint8Array ✓ (via explicit early return)

@kazrael2119
Copy link
Copy Markdown
Member

@copilot revert commit 471b877

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot revert commit 471b877

Reverted in commit 771f68e. The isBinaryPayload loop is back to the plain || condition from commit 4257998.

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.

[typespec-ts] */* content type should be treated as binary when body is bytes

2 participants