Skip to content

RLC: bytes request body emits NodeJS.ReadableStream union arm, breaking browser build (TS2503) #3990

@siddharthUCD

Description

@siddharthUCD

Package
@azure-tools/typespec-ts (RLC emitter)

Summary
For an operation whose request body is bytes, the RLC emitter generates a parameter type that includes NodeJS.ReadableStream. The Azure SDK for JS browser tsconfig sets "types": [] and intentionally excludes @types/node, so the browser compile fails with TS2503: Cannot find namespace 'NodeJS'. Node CJS/ESM targets compile fine; only the browser target fails.

Affected spec / PR

Minimal TypeSpec that triggers it
`model SignedStatement {
@Header("Content-Type")
contentType: "application/cose";

@bodyRoot
body: bytes;
}

@post
@route("/entries")
op createEntry is Foundations.Operation<
SignedStatement & AcceptCoseOrCborHeader,
CreateEntryCreated | CreateEntryPending,
ServiceTraits,
AnyCborError

;`

Generated output (excerpt)
sdk/confidentialledger/codetransparency-rest/src/parameters.ts, line 53:
// Roughly: body: string | Uint8Array | ReadableStream<Uint8Array> | NodeJS.ReadableStream;

The NodeJS.ReadableStream arm is the offender.

Build error
sdk/confidentialledger/codetransparency-rest/src/parameters.ts(53,60): error TS2503: Cannot find namespace 'NodeJS'. [warp] Build failed for targets: browser ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL @azure-rest/codetransparency@1.0.0-beta.1 build

Repro steps

  1. Use any TypeSpec data-plane operation whose request body is bytes.
  2. Run the spec-gen-sdk pipeline (or locally: pnpm run --filter @azure-rest/<pkg>... build after generation).
  3. Browser target compilation fails with TS2503 on the generated parameters.ts.

Expected behavior
The emitter should produce a type union for binary request bodies that compiles in both Node and browser targets. Options:

  • Replace NodeJS.ReadableStream with a structural type like AsyncIterable<Uint8Array>.
  • Or split the parameter type across src/node/ and src/browser/ files selected via the package.json exports node/browser conditions (consistent with how the rest of azure-sdk-for-js isolates Node-only APIs).

Actual behavior
A single parameters.ts with NodeJS.ReadableStream is emitted and consumed by all build targets, breaking the browser build wherever @types/node is excluded (which is repo policy).

Environment

  • Emitter: @azure-tools/typespec-ts (version used by spec-gen-sdk at run time — please confirm from your pipeline; see azure-sdk-for-js lockfile)
  • TypeScript: 6.0.3 (per the API Extractor warning in the build log)
  • azure-sdk-for-js: HEAD at time of pipeline run
  • Repo policy: Browser tsconfigs in azure-sdk-for-js set "types": [] to exclude @types/node

Workaround used in the spec repo
Added a client.tsp next to the spec narrowing the JS-side type:
@@alternateType(Microsoft.CodeTransparency.SignedStatement.body, string, "javascript");

This unblocks the pipeline but degrades JS ergonomics (callers must pass a base64-encoded string instead of a binary). We would like to remove the workaround once this is fixed upstream.

Impact
Blocks JS SDK generation for any data-plane service with binary request bodies. Other emitters (Python/C#/Java/autorest) are unaffected.

Metadata

Metadata

Labels

HRLCP1priority 1customer-reportedIssues that are reported by GitHub users external to the Azure organization.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions