-
Notifications
You must be signed in to change notification settings - Fork 83
Add reference documentation for TCGC diagnostics #4982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
aeb5b23
Add reference documentation for TCGC diagnostics
a91b36f
Enrich TCGC diagnostic docs to match openapi3 style
5326681
Address PR review: enrich/fix diagnostic docs and clean up diagnostics
7d1da03
Add diagnostic reference URLs and convert unreachable checks to compi…
dad4397
Raise severity of several TCGC diagnostics to error
63dd34e
Add test-grounded examples to diagnostics that had a test but no example
75e196d
Refine diagnostic docs: drop using lines and address review feedback
e85c7a8
Merge branch 'main' into tadelesh/tcgc-diagnostic-docs
tadelesh 5135fcf
Restructure diagnostic docs to match linter format
57347a0
Mark the key error line in each diagnostic Incorrect Usage example
4fe80a7
Drop the emoji from inline error markers in Incorrect Usage examples
22938a7
Show correct tsp in How to Fix and fix api-version-undefined config g…
972c2fd
Unify all diagnostic doc section headings to h2
86cd6f3
Nest triad headings under case headings in multi-case diagnostic docs
df96909
Address review: refine suppression guidance, simplify messages, prune…
c68ea45
Merge branch 'main' of github.com:Azure/typespec-azure into tadelesh/…
0dfb027
Align core submodule with main (no net change)
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| changeKind: internal | ||
| packages: | ||
| - "@azure-tools/typespec-client-generator-core" | ||
| --- | ||
|
|
||
| Add reference documentation for TCGC diagnostics so each diagnostic gets an auto-generated reference page. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
packages/typespec-client-generator-core/src/diagnostics/add-parameter-duplicate.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| This diagnostic is issued when `addParameter` is called with a model property whose name already exists on the operation. | ||
|
|
||
| ## Impact | ||
|
|
||
| - **Area:** Client customization transformations. Blocks `addParameter` from producing a valid customized SDK method signature when the added parameter name already exists. | ||
| - **Not affected:** The original service operation remains unchanged. | ||
|
|
||
| ## ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace MyService { | ||
| op myOp(name: string): void; | ||
| } | ||
|
|
||
| model ExtraParams { | ||
| name: string; // duplicates existing parameter `name` on `myOp` | ||
| } | ||
| alias Modified = addParameter(MyService.myOp, ExtraParams.name); | ||
| ``` | ||
|
|
||
| ## Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| Parameter "name" already exists in operation "myOp". | ||
| ``` | ||
|
|
||
| ## ✅ How to Fix | ||
|
|
||
| Choose a unique parameter name or use `replaceParameter` when the intent is to replace an existing parameter. | ||
|
tadelesh marked this conversation as resolved.
|
||
|
|
||
| ```typespec | ||
| @service | ||
| namespace MyService { | ||
| op myOp(name: string): void; | ||
| } | ||
|
|
||
| model ExtraParams { | ||
| description: string; | ||
| } | ||
| alias Modified = addParameter(MyService.myOp, ExtraParams.description); | ||
| ``` | ||
48 changes: 48 additions & 0 deletions
48
packages/typespec-client-generator-core/src/diagnostics/api-version-undefined.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| This diagnostic is issued when the `api-version` emitter option names a version that is not present in the service versioning list. | ||
|
|
||
| ## Impact | ||
|
|
||
| - **Area:** API-version option resolution. Generation continues by falling back to the latest defined service version, which can target a different SDK API version than requested. | ||
| - **Not affected:** The service's declared version enum and versioned TypeSpec projections are unchanged. | ||
|
|
||
| ## ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| @service(#{ title: "Contoso Widget Manager" }) | ||
| @versioned(Contoso.WidgetManager.Versions) | ||
| namespace Contoso.WidgetManager; | ||
|
|
||
| enum Versions { | ||
| v1, | ||
| v2, | ||
| v3, | ||
| } | ||
| ``` | ||
|
|
||
| ```yaml | ||
| options: | ||
| "@azure-tools/typespec-python": | ||
| api-version: "v4" # v4 is not one of v1/v2/v3 | ||
| ``` | ||
|
|
||
| ## Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| The API version specified in the config: "v4" is not defined in service versioning list. Fall back to the latest version. | ||
| ``` | ||
|
|
||
| ## ✅ How to Fix | ||
|
|
||
| Set `api-version` to a service version that exists. `latest` and `all` are also valid values when those behaviors are intended. | ||
|
|
||
| ```yaml | ||
| options: | ||
| "@azure-tools/typespec-python": | ||
| api-version: "v3" | ||
| ``` | ||
|
|
||
| ## Suppression | ||
|
|
||
| This diagnostic should not be suppressed. Fix the configured `api-version` value in `tspconfig.yaml` so it matches the service versioning list, or use `latest` or `all` intentionally. |
77 changes: 77 additions & 0 deletions
77
...s/typespec-client-generator-core/src/diagnostics/auto-merge-service-conflict.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| This diagnostic is issued when a parent client uses `autoMergeService` and a nested client also specifies its own service configuration. | ||
|
|
||
| ## Impact | ||
|
|
||
| - **Area:** Multi-service client hierarchy. Blocks an auto-merged parent client from also containing a nested client with its own explicit service binding. | ||
| - **Not affected:** The underlying service namespaces and routes remain valid independently. | ||
|
|
||
| ## ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace ServiceA { | ||
| @route("/aTest") | ||
| op opA(): void; | ||
| } | ||
|
|
||
| @service | ||
| namespace ServiceB { | ||
| @route("/bTest") | ||
| op opB(): void; | ||
| } | ||
|
|
||
| @client({ | ||
| name: "ParentClient", | ||
| service: [ServiceA, ServiceB], | ||
| autoMergeService: true, | ||
| }) | ||
| namespace ParentClient { | ||
| @client({ | ||
| name: "ChildClient", | ||
| service: ServiceA, // child service conflicts with the parent's `autoMergeService` | ||
| }) | ||
| namespace Child { | ||
|
|
||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| Auto-merging service client must be empty. | ||
| ``` | ||
|
|
||
| ## ✅ How to Fix | ||
|
|
||
| Leave the nested client's `service` option unset so it inherits from the parent, or remove the parent `autoMergeService` setup. | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace ServiceA { | ||
| @route("/aTest") | ||
| op opA(): void; | ||
| } | ||
|
|
||
| @service | ||
| namespace ServiceB { | ||
| @route("/bTest") | ||
| op opB(): void; | ||
| } | ||
|
|
||
| @client({ | ||
| name: "ParentClient", | ||
| service: [ServiceA, ServiceB], | ||
| autoMergeService: true, | ||
| }) | ||
| namespace ParentClient { | ||
| @client({ | ||
| name: "ChildClient", | ||
| }) | ||
| namespace Child { | ||
|
|
||
| } | ||
| } | ||
| ``` |
187 changes: 187 additions & 0 deletions
187
...ages/typespec-client-generator-core/src/diagnostics/client-location-conflict.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| This diagnostic is issued when a `@clientLocation` move conflicts with the client structure TCGC is building. It is reported in several situations: | ||
|
|
||
| - **String target with multiple root clients** — a string target cannot be resolved when more than one root client exists, because TCGC cannot decide which root client should own the new sub client. | ||
| - **Moving an operation onto another operation** — an operation can only be moved to an interface or namespace, not onto another operation. | ||
| - **Moving a model property to a string target** — a model property can only be moved to an interface or namespace, not to a string-named target. | ||
| - **Parameter name already used in client initialization** — the parameter produced by the moved model property collides with an existing client initialization parameter. | ||
| - **Same parameter moved with different types** — the same parameter name is moved to one client with conflicting types, which commonly happens when `@clientLocation` is applied to a templated parameter that is instantiated with different types. | ||
|
|
||
| ## Impact | ||
|
|
||
| - **Area:** Client operation and parameter placement. Generation continues, but the requested `@clientLocation` move cannot be applied safely to the generated client structure. | ||
| - **Not affected:** HTTP routes, parameter wire names, and service operation definitions are unchanged. | ||
|
|
||
| ## String target with multiple root clients | ||
|
|
||
| ### Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| @clientLocation with string target could not be used for multiple root clients scenario | ||
| ``` | ||
|
|
||
| ### ✅ How to Fix | ||
|
|
||
| Use an interface or namespace target when multiple root clients exist, or define the target sub client explicitly under the intended root client. | ||
|
|
||
| ## Operation to operation | ||
|
|
||
| ### Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| `@clientLocation` cannot be used to move an operation to another operation. Operations can only be moved to interfaces or namespaces. | ||
| ``` | ||
|
|
||
| ### ✅ How to Fix | ||
|
|
||
| Move the operation to an interface or namespace instead of another operation. | ||
|
|
||
| ## Model property conflicts with client initialization | ||
|
|
||
|
tadelesh marked this conversation as resolved.
|
||
| ### ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| model ClientOptions { | ||
| apiKey: string; | ||
| } | ||
|
|
||
| @clientInitialization(ClientOptions) | ||
| @service | ||
| namespace WidgetService { | ||
| model Widget { | ||
| @clientLocation(WidgetService) // conflicts with `apiKey` already in the client initialization model | ||
| apiKey: string; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| There is already a parameter called 'apiKey' in the client initialization. | ||
| ``` | ||
|
|
||
| ### ✅ How to Fix | ||
|
|
||
| Rename the moved property or the client-initialization parameter so they do not collide. | ||
|
|
||
| ```typespec | ||
| model ClientOptions { | ||
| apiKey: string; | ||
| } | ||
|
|
||
| @clientInitialization(ClientOptions) | ||
| @service | ||
| namespace WidgetService { | ||
| model Widget { | ||
| @clientLocation(WidgetService) | ||
| widgetApiKey: string; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Model property moved to string target | ||
|
|
||
| ### ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace WidgetService { | ||
| model Widget { | ||
| @clientLocation("SharedClient") // a model property can only be moved to an interface or namespace, not a string target | ||
| region: string; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| `@clientLocation` can only move model properties to interfaces or namespaces. | ||
| ``` | ||
|
|
||
| ### ✅ How to Fix | ||
|
|
||
| Move the model property to a concrete interface or namespace target instead of a string-named target. | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace WidgetService { | ||
| namespace SharedClient { | ||
|
|
||
| } | ||
|
|
||
| model Widget { | ||
| @clientLocation(SharedClient) | ||
| region: string; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Moved parameters with conflicting types | ||
|
|
||
| ### ❌ Incorrect Usage | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace Default; | ||
|
|
||
| union FeatureOptInKeys { | ||
| insights: "Insights.V1Preview", | ||
| schedules: "Schedules.V1Preview", | ||
| } | ||
|
|
||
| alias WithPreviewHeader<T extends FeatureOptInKeys> = { | ||
| @clientLocation(Default) // templated parameter moves different concrete types to the same client | ||
| @header("x-preview-features") | ||
| previewFeatures: T; | ||
| }; | ||
|
|
||
| op getInsights(...WithPreviewHeader<FeatureOptInKeys.insights>): void; | ||
| op getSchedules(...WithPreviewHeader<FeatureOptInKeys.schedules>): void; | ||
|
tadelesh marked this conversation as resolved.
|
||
| ``` | ||
|
tadelesh marked this conversation as resolved.
|
||
|
|
||
| ### Diagnostic Message | ||
|
|
||
| TCGC reports: | ||
|
|
||
| ```text | ||
| @clientLocation cannot move multiple parameters named 'previewFeatures' with different types to the same client. This often happens when @clientLocation is applied to a templated parameter that is instantiated with different types. Move the parameter on each operation instead, so that it has a consistent type on the client. | ||
| ``` | ||
|
|
||
| ### ✅ How to Fix | ||
|
|
||
| Move the parameter on each operation instead of on the templated alias, or ensure every moved `previewFeatures` parameter has the same type. | ||
|
|
||
| ```typespec | ||
| @service | ||
| namespace Default; | ||
|
|
||
| union FeatureOptInKeys { | ||
| insights: "Insights.V1Preview", | ||
| schedules: "Schedules.V1Preview", | ||
| } | ||
|
|
||
| op getInsights( | ||
| @clientLocation(Default) | ||
| @header("x-preview-features") | ||
| previewFeatures: FeatureOptInKeys, | ||
| ): void; | ||
|
|
||
| op getSchedules( | ||
| @clientLocation(Default) | ||
| @header("x-preview-features") | ||
| previewFeatures: FeatureOptInKeys, | ||
| ): void; | ||
| ``` | ||
|
|
||
| ## Suppression | ||
|
|
||
| This diagnostic should not be suppressed. Fix the `@clientLocation` usage as described in the cases above. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.