Skip to main content

tsp-naming-collision

Fix Java codegen parameter names that end with a numeric suffix (e.g. createAgentRequest1) caused by TypeSpec model names colliding with synthetic body type names. Use when generated Java client methods have parameter names ending in '1'.

Informations de source

Dépôt
Azure/azure-sdk-for-java
Dernière activité de la source
16 mars 2026 à 09:47
Langue détectée de SKILL.md
anglais
Étoiles
2 567
Forks
2 181

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
tsp-naming-collision
description
Fix Java codegen parameter names that end with a numeric suffix (e.g. createAgentRequest1) caused by TypeSpec model names colliding with synthetic body type names. Use when generated Java client methods have parameter names ending in '1'.
# Fix TypeSpec Naming Collisions in Java Codegen Fix parameter and implementation-model names that end with a numeric suffix (e.g. `createAgentRequest1`) in generated Java client code. This happens when a TypeSpec **named `model`** collides with the **synthetic body type** the Java codegen creates for an operation that spreads that model. ## Root Cause When a TypeSpec route **spreads** a named model into an operation's parameters (via `...ModelName`), the Java codegen creates a synthetic body type to hold the body properties. It names this type `{OperationName}Request` (PascalCase of the operation name + `Request`). If a TypeSpec `model` already has that exact name, the codegen resolves the collision by appending `1`. Example collision: - TypeSpec model: `CreateAgentRequest` - Operation: `createAgent` spreads `...CreateAgentRequest` - Codegen synthetic body: wants name `CreateAgentRequest` → collision → `CreateAgentRequest1` - Result: parameter `createAgentRequest1`, implementation class `CreateAgentRequest1.java` > **Why aliases don't collide:** TypeSpec `alias` declarations don't occupy a name in the type namespace, so there is no collision. If the upstream spec used `alias CreateAgentRequest = { ... }` instead of `model CreateAgentRequest { ... }`, no fix would be needed. ## Preconditions - You must be in the directory that contains `tsp-location.yaml`. - The TypeSpec must already be synced locally into `TempTypeSpecFiles/`. If not, run `tsp-client sync` first. - Identify the `client.tsp` file inside `TempTypeSpecFiles/` (usually under a subdirectory like `sdk-agents/`). This is the customization file where fixes are applied. ## Important: TempTypeSpecFiles is volatile `TempTypeSpecFiles/` is regenerated on every `tsp-client sync` or `tsp-client update`. **Changes made only in `TempTypeSpecFiles/` will be lost.** Always apply the same edits to the corresponding `client.tsp` in a local checkout of `Azure/azure-rest-api-specs` (if available) so the changes can be committed to a PR. ## Workflow ### 1. Identify affected operations Search the generated Java client classes for parameter names ending with `1`: ```bash grep -n 'Request1[,)]' src/main/java/com/azure/ai/agents/*Client.java ``` Also check for implementation model classes with the `1` suffix: ```bash find . -name "*Request1.java" -path "*/implementation/models/*" ``` Collect the list of affected names (e.g. `createAgentRequest1`, `updateAgentRequest1`). ### 2. Trace back to the TypeSpec models For each affected parameter, find the TypeSpec model that causes the collision. The model name matches the parameter name (PascalCase, without the `1`). Search the `.tsp` files: ```bash grep -rn "model CreateAgentRequest\|model UpdateAgentRequest" TempTypeSpecFiles/ --include="*.tsp" ``` Confirm the model is used via spread (`...ModelName`) in the route definitions: ```bash grep -rn "CreateAgentRequest\|UpdateAgentRequest" TempTypeSpecFiles/ --include="*.tsp" ``` Verify the model is a `model` (not an `alias`). Only named `model` types cause collisions. ### 3. Add `@@clientName` overrides Edit the `client.tsp` customization file in `TempTypeSpecFiles/`. Add a `@@clientName` directive for each colliding model to give it a different client-side name. This frees the original name for the codegen's synthetic body type. Use a consistent naming convention. Recommended: rename `*Request` → `*Input`: ```tsp // Rename request models to avoid collision with synthetic body types generated // by the Java codegen. The codegen names synthetic bodies as {OperationName}Request, // which clashes with the identically-named TypeSpec models, causing a "1" suffix. @@clientName(CreateAgentRequest, "CreateAgentInput"); @@clientName(UpdateAgentRequest, "UpdateAgentInput"); ``` > **Note:** These models are typically not emitted as public Java classes — they only exist to be spread into operations. The rename is purely internal and does not affect the public API surface. ### 4. Regenerate and verify Generate with `--save-inputs` to preserve the edited TypeSpec files: ```bash tsp-client generate --save-inputs ``` Verify the `1` suffix is gone: ```bash # Should return zero matches grep -c "Request1" src/main/java/com/azure/ai/agents/*Client.java # Old *Request1.java files should no longer exist find src -name "*Request1.java" -path "*/implementation/models/*" # New clean-named files should exist find src -name "*Request.java" -path "*/implementation/models/*" ``` Compile to confirm no breakage: ```bash mvn compile -Denforcer.skip=true -Dcodesnippet.skip=true -Dcheckstyle.skip=true \ -Dspotbugs.skip=true -Dspotless.skip=true -Drevapi.skip=true -Djacoco.skip=true \ -Dmaven.javadoc.skip=true -Dshade.skip=true -Danimal.sniffer.skip=true ``` ### 5. Apply changes to the local spec repo (if available) If the user has a local checkout of `Azure/azure-rest-api-specs`, apply the **same `client.tsp` edits** there. Derive the file path from `tsp-location.yaml`: - `directory` field gives the relative spec path (e.g. `specification/ai-foundry/data-plane/Foundry/src/sdk-agents`) - The file to edit is `client.tsp` inside that directory For example, if the local repo is at `<local-spec-repo>`: ``` <local-spec-repo>/specification/ai-foundry/data-plane/Foundry/src/sdk-agents/client.tsp ``` Verify the file exists before editing. If it doesn't, warn the user and print the expected path. ### 6. Full round-trip from the remote spec (optional) If the user wants to validate the fix end-to-end from the remote repo: 1. Commit and push the `client.tsp` changes in the spec repo 2. Get the new commit hash 3. Update the `commit:` field in `tsp-location.yaml` with the new hash 4. Run `tsp-client update` to sync and regenerate from the remote 5. Verify the `1` suffix is gone and the build compiles ## Troubleshooting | Symptom | Cause | Fix | |---------|-------|-----| | `1` suffix persists after adding `@@clientName` | The `@@clientName` target doesn't match the TypeSpec model name exactly | Double-check the model name is the TypeSpec name (not the Java name); names are case-sensitive | | New suffix appears (e.g. `2`) | Multiple models collide with the same synthetic name | Ensure every colliding model has a unique `@@clientName` | | Build fails after regeneration | Handwritten code references the old `*1` names | Update any manual references in custom client code, tests, or samples | | Changes lost after `tsp-client sync` | `TempTypeSpecFiles/` was overwritten | Apply changes to the spec repo `client.tsp` (see step 5) |
Voir sur GitHub