Skip to content

[typespec-ts] Empty resourceUri for tenant-scoped extension resources generates a double-slash URL #5314

Description

Describe the bug

The TypeScript emitter generates a URL template with a slash on both sides of the extension-resource scope parameter:

"/{+resourceUri}/providers/Azure.ResourceManager.Resources/extensionsResources/{extensionsResourceName}{?api%2Dversion}"

For tenant-scoped extension resources, resourceUri is correctly passed as an empty string. Expanding the template then produces a route beginning with two slashes:

//providers/Azure.ResourceManager.Resources/extensionsResources/extension

The Spector server does not match this route and returns 404.

Reproduction

Use the azure/resource-manager/resources Spector scenario and run:

await client.extensionsResources.get("", "extension");

The same problem affects all tenant-scoped extension-resource operations currently covered by packages/typespec-ts/test/azure-modular-integration/azure-arm-resources.test.ts:

  • get("", "extension")
  • createOrUpdate("", "extension", resource)
  • update("", "extension", resource)
  • delete("", "extension")
  • listByScope("")

Expected behavior

The request URL contains a single slash before providers:

/providers/Azure.ResourceManager.Resources/extensionsResources/extension

An empty resource URI represents tenant scope. Callers should not need to pass "." or another placeholder to obtain the correct URL.

Actual behavior

The generated requests contain //providers/... and receive 404 responses. For example:

GET //providers/Azure.ResourceManager.Resources/extensionsResources/extension?api-version=2023-12-01-preview 404

The PUT, PATCH, DELETE, and list operations fail in the same way.

Root cause

The generated expandUrlTemplate call expands this template:

/{+resourceUri}/providers/...

With resourceUri === "", the parameter contributes no characters while both literal slashes remain.

@typespec/ts-http-runtime@0.3.7 intentionally preserves consecutive slashes inside a route path. Azure SDK for JS PR Azure/azure-sdk-for-js#37302 removed the previous global slash normalization from buildRequestUrl and limits normalization to the endpoint/route boundary. Therefore, the runtime does not normalize this generated internal //.

Suggested fix

Have the TypeScript emitter generate or expand the route so tenant scope produces /providers/... directly, without relying on runtime slash normalization. The fix should preserve the empty-string API for tenant scope and should not require the "." workaround.

Environment

  • @azure-tools/typespec-ts: 0.56.0
  • @typespec/ts-http-runtime: 0.3.7
  • @azure-rest/core-client: 2.8.0
  • TypeSpec compiler: 1.14.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    emitter:typescriptIssues for @azure-tools/typespec-ts emitter

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions