Skip to content

Fix per-client ServiceVersion regression in http-client-java#11286

Merged
XiaofeiCao merged 2 commits into
microsoft:mainfrom
XiaofeiCao:xiaofeicao/fix-per-client-serviceversion
Jul 17, 2026
Merged

Fix per-client ServiceVersion regression in http-client-java#11286
XiaofeiCao merged 2 commits into
microsoft:mainfrom
XiaofeiCao:xiaofeicao/fix-per-client-serviceversion

Conversation

@XiaofeiCao

Copy link
Copy Markdown
Member

Fixes per-client ServiceVersion regression

Problem

For a package containing multiple TypeSpec clients, the emitter is supposed to generate a single shared ServiceVersion enum (named after the package/service) when all clients use the same api-versions, and only fall back to a per-client <ClientName>ServiceVersion when the clients genuinely have different api-versions.

Recently, multi-client packages started generating a separate ServiceVersion enum per client even when all clients share the same api-versions, e.g.:

  • azure-search-documents: SearchServiceVersionSearchIndexServiceVersion, SearchIndexerServiceVersion, KnowledgeBaseRetrievalServiceVersion
  • azure-developer-devcenter: DevCenterServiceVersionDevCenterServiceVersion, DevBoxesServiceVersion, DeploymentEnvironmentsServiceVersion
  • azure-communication-messages, eventgrid-namespaces, etc.

Root cause

In code-model-builder.ts, the "same api-versions for all clients" check was changed in #11134 (replacing lodash.isEqual with a built-in comparison):

// before
apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
// after
apiVersionSameForAllClients =
  sharedApiVersions.length === apiVersions.length &&
  sharedApiVersions.every((it, index) => it === apiVersions[index]);

apiVersions is ApiVersion[] (objects), not string[]. Each client builds its own ApiVersion instances:

const apiVersion = new ApiVersion();
apiVersion.version = version.value;
codeModelClient.apiVersions.push(apiVersion);

lodash.isEqual did a deep value comparison (equal versions → treated as equal), but === compares object references, which is always false for distinct instances. As a result apiVersionSameForAllClients became false for every multi-client package, triggering the per-client ServiceVersion branch.

Fix

Compare the api-version strings instead of the ApiVersion object references:

apiVersionSameForAllClients =
  sharedApiVersions.length === apiVersions.length &&
  sharedApiVersions.every((it, index) => it.version === apiVersions[index].version);

This restores a single shared ServiceVersion for multi-client packages whose clients use the same api-versions, while still producing per-client ServiceVersion enums when the api-versions actually differ.

Notes

The ServiceVersion postprocess decides whether a multi-client package gets a single
shared ServiceVersion enum or one enum per client, based on whether all clients share
the same api-versions. That comparison was changed (PR microsoft#11134, replacing lodash.isEqual
with a built-in) to compare ApiVersion values with '==='. Because each client builds its
own ApiVersion instances (new ApiVersion()), '===' compares object references and is
always false for distinct instances, so every multi-client package incorrectly generated
a separate <ClientName>ServiceVersion enum per client.

Compare the api-version strings (it.version) instead of the object references, restoring
a single shared ServiceVersion when all clients use the same api-versions.
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:java Issue for the Java client emitter: @typespec/http-client-java label Jul 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @typespec/http-client-java
Show changes

@typespec/http-client-java - fix ✏️

Fix multi-client packages generating a separate ServiceVersion enum per client when all clients share the same api-versions. The api-version comparison now compares version strings instead of ApiVersion object references, restoring a single shared ServiceVersion for such packages.

@azure-sdk-automation

azure-sdk-automation Bot commented Jul 17, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

Adds tsp/multiple-clients-same-version.tsp: a single versioned service split into two
clients (AlphaClient, BetaClient) that share the same api-versions, plus the generated
Java output. This case previously had no coverage - the only multi-client e2e spec
(multiple-services) uses different api-versions per service, where per-client
ServiceVersion is correct - which is why the regression went undetected.

The generated code contains a single shared MultipleClientsSameVersionServiceVersion enum
(referenced by both AlphaClientBuilder and BetaClientBuilder), not a per-client
<ClientName>ServiceVersion. With the bug (comparing ApiVersion object references), this
spec instead generates AlphaServiceVersion + BetaServiceVersion, so the codegen-diff CI
check fails - giving us regression coverage.
@XiaofeiCao
XiaofeiCao marked this pull request as ready for review July 17, 2026 05:30
@XiaofeiCao
XiaofeiCao added this pull request to the merge queue Jul 17, 2026
Merged via the queue into microsoft:main with commit d31aefe Jul 17, 2026
35 checks passed
@XiaofeiCao
XiaofeiCao deleted the xiaofeicao/fix-per-client-serviceversion branch July 17, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:java Issue for the Java client emitter: @typespec/http-client-java

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants