Skip to content

ARM Rules, TypeSpec Linting, and Suppression

ARM includes many rules on the structure of resources and the details of resource operations that ensure a consistent user experience when managing services inside Azure. TypeSpec encodes many fo these rules into linting checks that occur on each compilation. If you use an IDE and install the TypeSpec IDE Tools, violations of rules will show up as yellow highlights in your tsp code. If you hover over these, you will get a message indicating the issue and how to fix it in your specification. If you use the typespec command-line, violations of rules will be printed as warnings, with a description and steps to correct the issue, and a pointer to the location in the specification where the violation occurred.

In the sections below, we will discuss these rules, how they work, and, in cases where a violation is a false positive, or has a reason approved by an ARM reviewer, can be suppressed.

TypeSpec has a set of linting rules that execute whenever the specification is compiled, and in the IDE as you type. Violations are highlighted inline in the spec, or emitted during compilation.

For more information, see ARM RPC rules

Detecting and Suppressing Rule Violations at Design Time

Section titled β€œDetecting and Suppressing Rule Violations at Design Time”

Violations of ARM RPC rules will show up at design time as a yellow highlight over the violating type in TypeSpec, and at compile time as an emitted warning with a specific reference in the specification code (line number, position, pointer).

Here is an example of a linter warning:

Terminal window
Diagnostics were reported during compilation:
C:/typespec-samples/resource-manager/zerotrust/main.tsp:38:3 - warning @azure-tools/typespec-azure-resource-manager/arm-resource-operation-missing-decorator: Resource POST operation must be decorated with @armResourceAction.
> 38 | /** Gets the Zero Trust URL for this resource */
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 39 | @post
| ^^^^^^^
> 40 | getZeroTrustUrl(...ResourceInstanceParameters<ZeroTrustResource>): ZeroTrustUrl | ErrorResponse;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Found 1 warning.

To suppress the warning, you would use the #suppress directive on the type that violates the rule. The directive takes the fully-qualified name of the rule you are suppressing, and a reason for the suppression.

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation-missing-decorator" "This is a sample suppression."
/** Gets the MAA URL for this resource */
@post
getZeroTrustUrl(...ResourceInstanceParameters<ZeroTrustResource>): ZeroTrustUrl | ErrorResponse;

Of course, in this case, the best resolution would be to follow the advice in the linting rule, and add the @armResourceAction decorator.

@armResourceAction(ZeroTrustResource)
/** Gets the MAA URL for this resource */
@post
getZeroTrustUrl(...ResourceInstanceParameters<ZeroTrustResource>): ZeroTrustUrl | ErrorResponse;

The table below provides guidance to rule authors and ARM reviewers on how to evaluate violations of TypeSpec ARM rules. For each rule, it describes the area it affects, any corresponding LintDiff rule, the impact of a violation, when a suppression is appropriate, and how to fix the underlying problem. Rules are listed alphabetically by name.

RuleArea of impactLintDiffImpact descriptionWhen to suppressFix
@azure-tools/typespec-azure-core/auth-requiredAPI, SDKβ€”None; all ARM APIs allow the same authentication.Should never occur.Add @armProviderNamespace to the root namespace.
@azure-tools/typespec-azure-core/byosAPIβ€”The API uses file upload and download instead of a storage account.If appropriate for the API.Use a storage account to upload and download large artifacts.
@azure-tools/typespec-azure-core/casing-styleAPI, SDKDefinitionsPropertiesNamesCamelCase (covers the serious violation)On properties, this produces non-standard casing that impacts usability. On other types, emitters substitute the correct casing for their language.Only when required on properties; otherwise it is acceptable to suppress.Use standard casing for each type: PascalCase for namespaces, interfaces, models, unions, and enums; camelCase for properties, parameters, operations, and scalars.
@azure-tools/typespec-azure-core/composition-over-inheritanceSDKβ€”Overuse of inheritance impacts SDK usability.If required.Use model is or spread (...) instead of extending a model.
@azure-tools/typespec-azure-core/documentation-requiredAPI, SDK*SummaryOrDescriptionResults in poor documentation in SDKs and API docs.Never.Add a /** */ comment or an @doc decorator.
@azure-tools/typespec-azure-core/friendly-nameAPI evolutionβ€”Names a type for emitters in an unscoped way; @clientName should be used instead.Never.Use @clientName instead.
@azure-tools/typespec-azure-core/key-visibility-requiredAPI, SDKβ€”May inaccurately represent the mutability of identity fields.If an identity field is genuinely mutable.Add a visibility decorator with the appropriate lifecycle visibility.
@azure-tools/typespec-azure-core/known-encodingAPI, SDKValidFormatsImpacts API and SDK usability; non-standard formats are transmitted only as the unencoded wire type.Only if needed to match existing APIs.Use standard formats, encodings, and types.
@azure-tools/typespec-azure-core/long-running-polling-operation-requiredSDK, APIβ€”Inapplicable to ARM LROs, but prevents an API from being represented as an LRO.Never, unless it is a false positive.Use the standard Async templates.
@azure-tools/typespec-azure-core/no-case-mismatchSDKβ€”Type names that differ only by casing prevent SDK generation.Only if the type names are renamed with client SDK decoration.Make type names unique when compared case-insensitively.
@azure-tools/typespec-azure-core/no-error-status-codesAPINoErrorCodeResponsesUsing status codes in a non-standard way makes APIs difficult to use.Only if needed to match existing APIs.Use standard operation templates.
@azure-tools/typespec-azure-core/no-explicit-routes-resource-opsAPIβ€”May indicate non-standard resource paths.If the path is most easily represented as a static route (for example, Network implementing Microsoft.Compute APIs for VMSS).Use standard templates.
@azure-tools/typespec-azure-core/no-fixed-enum-discriminatorAPIβ€”Makes adding a new discriminant value a breaking change.Only if there will never be new leaf types.Use an open enumeration as the discriminator.
@azure-tools/typespec-azure-core/no-formatSDK, APIβ€”May use an invalid format.If a valid format is used, suppression is acceptable.Use standard types, which automatically use the correct wire format, or @encode when a non-standard format is necessary (for example, base64url).
@azure-tools/typespec-azure-core/no-generic-numericSDKValidFormatsSDKs lose precision or cannot represent the value with a strong numeric type.Only if needed to match existing APIs.Use defined numeric types for floating-point, fixed-point, and integer numbers.
@azure-tools/typespec-azure-core/no-header-explodeAPIβ€”Mainly a data-plane concern, but explode should not be allowed for headers.Only if needed to match existing APIs.Use other separators for multi-value headers.
@azure-tools/typespec-azure-core/no-legacy-usageAPI, SDKβ€”Uses legacy patterns instead of standard patterns.Only if needed to match existing APIs.Use standard types and templates.
@azure-tools/typespec-azure-core/no-multiple-discriminatorSDK, APIβ€”Multiple discriminators are not supported by SDKs, nor by Swagger without extensions.Requires SDK approval.Use a single discriminator; refactor additional discriminators onto child or sibling properties.
@azure-tools/typespec-azure-core/no-nullableAPI, SDKβ€”This is usually a mistake where the property should be optional.Only if needed to match existing APIs.Use optional properties.
@azure-tools/typespec-azure-core/no-offsetdatetimeSDK, APIβ€”Reduces clarity of purpose; a time is best provided in UTC.If there is a reasonable rationale for OffsetDateTime.Use utcDateTime.
@azure-tools/typespec-azure-core/no-openapiAPI, SDK, Emittersβ€”Introduces OpenAPI changes that are not reflected in other emitters such as SDKs, which can cause SDKs to misrepresent the wire API.Acceptable only for @externalDocs or extensions that don’t affect the API or SDK (for example, x-ms-identifiers). Extensions such as x-ms-pageable, x-ms-long-running-operation, and x-ms-long-running-operation-options should never be allowed.Replace x-ms-pageable with @list; replace x-ms-long-running-* with the Async operation template; replace x-ms-secret with @secret or a password type; replace @operationId with @clientLocation or @clientName.
@azure-tools/typespec-azure-core/no-private-usageAPI, SDKβ€”May cause a spec break in the future.Only if needed to match existing APIs.Use standard types and templates.
@azure-tools/typespec-azure-core/no-query-explodeAPIβ€”Mainly a data-plane concern, but explode should not be allowed for query parameters.Only if needed to match existing APIs.Use other separators for multi-value query parameters.
@azure-tools/typespec-azure-core/no-rest-library-interfacesSDK, Emittersβ€”If used to describe resource APIs, emitters may not recognize them as such, though this would produce other violations.Acceptable if there are no other violations.Use the standard operation templates.
@azure-tools/typespec-azure-core/no-route-parameter-name-mismatchSDKβ€”When representing operations over a resource, mismatched parameters can produce strange SDK operation signatures.If it is a false positive (which has a somewhat high rate).Use the standard resource operation templates.
@azure-tools/typespec-azure-core/no-rpc-path-paramsn/aβ€”There are no violations in ARM.n/an/a
@azure-tools/typespec-azure-core/no-string-discriminatorSDKβ€”Makes the SDK less usable because discriminant values are unknown.Only if needed to match existing APIs.Use an open union as the discriminator.
@azure-tools/typespec-azure-core/no-unknownAPI, SDKβ€”Allowing any JSON type makes SDKs and APIs unusable without extensive documentation.Treat it like a type without a schema or a type using additionalProperties.Use a concrete type.
@azure-tools/typespec-azure-core/no-unnamed-unionSDK, APIβ€”Causes the SDK to use an unnamed type.Only if needed to match existing APIs.Use a named union.
@azure-tools/typespec-azure-core/operation-missing-api-versionAPI, SDKApiVersionParameterRequiredAn unversioned operation cannot evolve.Never, unless it is a false positive.Use standard templates.
@azure-tools/typespec-azure-core/request-body-problemAPI, SDKβ€”A request body that is an array makes API evolution difficult.In actions where an array is appropriate.Use a keyed type with an array property, which allows adding new properties in the future.
@azure-tools/typespec-azure-core/require-versionedSDK, APIβ€”Prevents updating the API with new api-versions.Never.Add a Versions enum and reference it in the @versioned decorator on the root namespace.
@azure-tools/typespec-azure-core/response-schema-problemAPI, SDKβ€”May indicate a forgotten response status code.If a single response is appropriately represented as an inline union (unlikely).Use standard templates.
@azure-tools/typespec-azure-core/spread-discriminated-modelSDKβ€”May indicate a mistake, because a discriminator is ineffective when spread.If intended (unlikely).Only spread non-discriminated types.
@azure-tools/typespec-azure-core/use-extensible-enum, @azure-tools/typespec-azure-core/no-closed-literal-union, @azure-tools/typespec-azure-core/no-enumSDK, APIβ€”Prevents adding values to an enum in new api-versions without a breaking change.When the set of values is inherently immutable (for example, IPv4/IPv6).Use an open union, for example union These { This: "this", That: "that", string }.
@azure-tools/typespec-azure-resource-manager/arm-common-types-versionAPI, SDKβ€”Indicates that common-types are not used, though this should produce other violations.If common-types are never used and this is valid.Associate a common-types version with each version in the Versions enum.
@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-keyAPI, SDKβ€”Mainly a correctness issue; the name property should use @key.Only if needed to match existing APIs.Add @key to the name parameter for the resource.
@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourageAPIβ€”The resource does not use ARM common-types.Treat it like any resource not using common-types.Use TrackedResource, ProxyResource, or ExtensionResource.
@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codesAPIDeleteResponseCodesRPC violation.Only if needed to match existing APIs.Use the standard delete operation templates.
@azure-tools/typespec-azure-resource-manager/arm-legacy-operations-discourageAPI, SDKβ€”Indicates the use of one or more legacy patterns; important violations will appear in other rules.Only if needed to match existing APIs.Use standard types and templates.
@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflictsAPI, SDKβ€”Different-case paths to the same resource can cause ARM manifest failures.Never, unless it is a false positive.Normalize the casing of the path.
@azure-tools/typespec-azure-resource-manager/arm-no-recordAPI, SDKAvoidAdditionalPropertiesDictionary types make the API and SDK difficult to use.Only if needed to match existing APIs.Use a defined type instead.
@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codesAPIPostResponseCodesRPC violation.Only if needed to match existing APIs.Use the standard resource action or provider action templates.
@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codesAPIPutResponseCodesRPC violation.Only if needed to match existing APIs.Use the standard createOrUpdate operation templates.
@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segmentAPI, SDKPathForResourceAction (partial)May indicate a violation of the resource action path.If the actual path works.Use @action to define the final path segment with the standard resource action templates.
@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-propertyAPIArmResourcePropertiesBagRPC violation.Only if needed to match existing APIs.Do not reuse envelope property names in the resource-provider-specific property bag.
@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decoratorn/aβ€”No impact beyond what other rules cover.n/an/a
@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verbAPI, SDKβ€”An improper HTTP verb for a resource action can cause failures in the C# SDK and in emitters that model resource actions, such as service generation and the portal.Treat it like an improper resource action is treated today.Use resource action templates and do not override the verb with @put, @patch, @delete, or @head.
@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-propertyAPIBodyTopLevelPropertiesRPC violation.Only if needed to match existing APIs.Use the standard property mix-ins.
@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-formatAPIApiVersionPatternRPC violation.Only if needed to match existing APIs.Use the YYYY-MM-DD[-preview] format.
@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-charsSDKβ€”The resource parameter name produces invalid keys in SDKs.Never.Use the correct name in @key or the ResourceNameParameter template.
@azure-tools/typespec-azure-resource-manager/arm-resource-name-patternAPIResourceNameRestrictionRPC violation.Only if needed to match existing APIs.Use @pattern or the ResourceNameParameter template with a pattern string or union type.
@azure-tools/typespec-azure-resource-manager/arm-resource-operation-responseAPIPutGetPatchResponseSchema (the TypeSpec rule also covers list)RPC violation.Only if needed to match existing APIs.Use standard operation templates and do not override the response parameter.
@azure-tools/typespec-azure-resource-manager/arm-resource-operationSDK, API, Emittersβ€”Missing these decorators can prevent operations from being associated with the correct resource. This breaks the C# SDK and prevents reasoning about and linting resource-based rules, as well as producing correct resource-centric content such as service generation, tests, linting rules, and portal experiences.Requires sign-off for the C# SDK; check other violations carefully.Use standard resource types, or decorate with @customAzureResource when that is not possible. Use operation templates.
@azure-tools/typespec-azure-resource-manager/arm-resource-patchAPIConsistentPatchPropertiesRPC violation.Per RPC guidelines.Use standard Patch operations.
@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-charsSDK, APIβ€”Produces an invalid ARM API and invalid parameter names.Treat it like any invalid path segment and require a fix.Change the segment to use only valid characters.
@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-stateAPIProvisioningStateValidation, ProvisioningStateSpecifiedForLROPut, ProvisioningStateSpecifiedForLROPatch, RpaaS_ResourceProvisioningStateRPC / RPaaS violation.Per RPC guidelines.Define a ProvisioningState property with Succeeded, Failed, and Cancelled states.
@azure-tools/typespec-azure-resource-manager/beyond-nesting-levelsAPITrackedResourceBeyondsThirdLevelRPC violation.Per RPC guidelines.Avoid more than three levels of nesting in the resource layout.
@azure-tools/typespec-azure-resource-manager/empty-updateable-propertiesAPIβ€”Covered by patch-specific rules.Only if needed to match existing APIs, or when using Tags Patch.Ensure that not all properties in the properties bag are updateable.
@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operationAPIβ€”Likely a modeling error; only subscription-based resources should have list operations.Per RPC.Ensure tenant resources have only a tenant list, and use standard resource operations.
@azure-tools/typespec-azure-resource-manager/lro-location-headerAPILroLocationHeaderRPC violation.Per RPC guidelines.Use the standard Async templates.
@azure-tools/typespec-azure-resource-manager/missing-operations-endpointAPIOperationsAPIImplementationRPC violation.A few specs may not need this.Use the standard Operations template.
@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiersAPIXmsIdentifierValidation (warning)No real impact (an old pattern).At will.n/a
@azure-tools/typespec-azure-resource-manager/no-empty-modelAPI, SDKMissingTypeObjectAccepting any schema makes the API and SDK difficult to use.Only if needed to match existing APIs.Use a defined type instead.
@azure-tools/typespec-azure-resource-manager/no-override-propsSDK, Toolingβ€”Violations can crash the breaking-change tool and are unsupported by most languages.Requires SDK sign-off.Remove overridden properties from the base type; represent them only in leaf types.
@azure-tools/typespec-azure-resource-manager/no-resource-delete-operationAPIAllTrackedResourcesMustHaveDeleteRPC violation.Per RPC guidelines.Add a standard delete operation for the resource.
@azure-tools/typespec-azure-resource-manager/no-response-bodyAPIβ€”A non-empty response, usually for a 202.At will for 202; never for 204.Use standard operation and response templates.
@azure-tools/typespec-azure-resource-manager/patch-envelopeAPIβ€”A Patch operation is missing updatable envelope properties.There are no hard rules, but patchable envelope properties should generally be standard.Include patchable versions of the envelope properties.
@azure-tools/typespec-azure-resource-manager/resource-nameAPI, SDKβ€”Invalid characters in a name violate the RPC and create invalid client parameter names, which prevents SDK generation.Treat it like an invalid resource name is treated today.Use only valid characters.
@azure-tools/typespec-azure-resource-manager/secret-propAPIXMSSecretInResponseRPC violation.Only if the property is not an actual secret.Mark the property as a password type or with the @secret decorator.
@azure-tools/typespec-azure-resource-manager/unsupported-typeSDKβ€”The data type cannot be modeled in SDKs.Requires SDK sign-off.Use standard schemas and built-in types.
@azure-tools/typespec-azure-resource-manager/version-progressionAPI, SDK, Toolingβ€”Out-of-order versions make specs unmaintainable, and versions with matching dates cause SDK problems.Never. All new api-versions must increase monotonically.Ensure all new versions are unique and increase monotonically from top to bottom in the Versions enum.
@azure-tools/typespec-client-generator-core/property-name-conflictSDKβ€”Not representable in the C# SDK.Only with an exception for the C# SDK.Ensure properties do not share the name of their containing type, or add client decoration to rename them for the C# SDK.
@azure-tools/typespec-client-generator-core/require-client-suffixSDKβ€”Clients do not follow the SDK naming guidelines.Only when a client decorator is added in the PR; there is no strong reason to suppress.This occurs only when the spec adds client-specific decoration, which should use the β€œClient” suffix in the provided client name.