Skip to content

@@clientName on discriminated union subtypes is ignored — generates original TypeSpec name instead of renamed name #3337

@yungshinlintw

Description

@yungshinlintw

Bug Report

Emitter Version

@azure-tools/typespec-java v0.44.6

Description

@@clientName directives for discriminated union subtypes are ignored during code generation. The emitter generates classes using the original TypeSpec model name instead of the @@clientName-specified name.

This is a regression — the GA version of our SDK (generated with an earlier emitter) correctly produced ContentArrayField, ContentStringField, etc. The new emitter produces ArrayField, StringField, etc., ignoring the @@clientName directives.

Repro

TypeSpec models (models.tsp):

model ArrayField extends ContentField {
  type: ContentFieldType.array;
  valueArray?: ContentField[];
}

model StringField extends ContentField {
  type: ContentFieldType.string;
  valueString?: string;
}
// ... other subtypes

Client customization (client.tsp) — source: client.tsp L207-L215:

@@clientName(StringField, "ContentStringField", "java");
@@clientName(DateField, "ContentDateField", "java");
@@clientName(TimeField, "ContentTimeField", "java");
@@clientName(NumberField, "ContentNumberField", "java");
@@clientName(IntegerField, "ContentIntegerField", "java");
@@clientName(BooleanField, "ContentBooleanField", "java");
@@clientName(ArrayField, "ContentArrayField", "java");
@@clientName(ObjectField, "ContentObjectField", "java");
@@clientName(JsonField, "ContentJsonField", "java");

Expected Behavior

The emitter should generate Java classes with the @@clientName-specified names:

  • ContentArrayField.java
  • ContentStringField.java
  • ContentNumberField.java
  • etc.

Actual Behavior

The emitter generates classes using the original TypeSpec model names, ignoring @@clientName:

  • ArrayField.java
  • StringField.java
  • NumberField.java
  • etc.

The base class ContentField.java discriminator also references the un-renamed names (ArrayField.fromJson() instead of ContentArrayField.fromJson()).

Impact

This is a breaking change for our published GA SDK (azure-ai-contentunderstanding). Our GA SDK exposes ContentArrayField, ContentStringField, etc. as public types that customers import and use with instanceof checks. Regenerating with the new emitter would rename these types, breaking all existing consumer code.

Our customization file (ContentUnderstandingCustomizations.java) also references these types by their @@clientName names and fails with:

java.lang.IllegalArgumentException: ContentArrayField does not exist in package com.azure.ai.contentunderstanding.models

Merged GA SDK (proof that older emitter correctly applied @@clientName)

Context

  • TypeSpec @@clientName directives: client.tsp L207-L215 (Java) and client.tsp L166-L174 (C#)
  • TypeSpec repo: azure-rest-api-specs-pr (private), PR #27815
  • SDK: azure-ai-contentunderstanding
  • API version: 2026-07-01-preview (base GA: 2025-11-01)
  • The same issue also affects the C# emitter (@azure-typespec/http-client-csharp) — microsoft/typespec#10657

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions