# 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'.

- Skill: `azure-azure-sdk-for-java/tsp-naming-collision` (Agent Skill)
- Install (CLI): `npx skillmds@latest add azure-azure-sdk-for-java/tsp-naming-collision`
- Raw SKILL.md: https://api.skillmd.com/api/skills/azure-azure-sdk-for-java/tsp-naming-collision/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: Azure (https://skillmd.com/u/azure-azure-sdk-for-java)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/azure-azure-sdk-for-java/tsp-naming-collision

---


# 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) |

