Skip to content

[http-client-csharp] Fix trailing path separator for optional path parameter#11096

Merged
JoshLove-msft merged 5 commits into
microsoft:mainfrom
JoshLove-msft:fix/optional-path-trailing-slash
Jun 29, 2026
Merged

[http-client-csharp] Fix trailing path separator for optional path parameter#11096
JoshLove-msft merged 5 commits into
microsoft:mainfrom
JoshLove-msft:fix/optional-path-trailing-slash

Conversation

@JoshLove-msft

Copy link
Copy Markdown
Contributor

Problem

When a route ends with an optional path parameter, the / separator preceding that segment was emitted unconditionally, leaving a dangling trailing slash when the value is null.

For example, /certificates/{certificate-name}/{certificate-version} (with certificate-version optional) generated:

uri.AppendPath(certificateName, true);
uri.AppendPath("/", false);            // emitted unconditionally
if ((certificateVersion != null))
{
    uri.AppendPath(certificateVersion, true);
}

So when certificateVersion is null the wire URL becomes /certificates/{name}/ instead of /certificates/{name}. Services (e.g. Key Vault) and recorded test cassettes expect no trailing slash.

The existing shouldPrependWithPathSeparator logic only handled the case where the preceding literal does not end in /; it missed the case where the separator had already been written unconditionally.

Fix

In RestClientProvider.AddUriSegments, when the upcoming path parameter is optional and the preceding literal ends with /, defer that trailing / so it is written together with the parameter value inside the null check:

uri.AppendPath(certificateName, true);
if ((certificateVersion != null))
{
    uri.AppendPath("/", false);
    uri.AppendPath(certificateVersion, true);
}

Required path parameters are unaffected.

Tests

  • Added TestBuildCreateRequestMethodWithOptionalPathParameter (+ golden file) covering the trailing optional-segment case.
  • Updated two ServerTemplate* tests that relied on the test factory's default isRequired: false for what were intended to be normal required path parameters.
  • Full Microsoft.TypeSpec.Generator.ClientModel suite passes (1440 tests).

Reported in Azure/azure-sdk-for-net#60162 (Bug A).

--generated by Copilot

When a route ends with an optional path parameter (e.g.
/items/{name}/{version} with optional version), the separator '/'
preceding the optional segment was emitted unconditionally, producing
/items/{name}/ when the value was null instead of /items/{name}.

Defer the trailing separator into the parameter's null check so it is
only written when the optional value is present.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jun 26, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11096

commit: 71235d4

@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@azure-sdk-automation

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@JoshLove-msft JoshLove-msft added this pull request to the merge queue Jun 29, 2026
@JoshLove-msft JoshLove-msft removed this pull request from the merge queue due to a manual request Jun 29, 2026
JoshLove-msft and others added 2 commits June 29, 2026 09:11
So the @next dependency bump (typespec-bump-deps) upgrades spec-api
alongside http-specs/spector. As a transitive-only dep it was pinned at
alpha.14, which lacks the match.string matcher used by newer http-specs
specs (e.g. encode/boolean), breaking the Spector test server.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 'az webapp config container set' step can fail with a transient
GatewayTimeout from Microsoft.Web even though the ACR image build/push
succeeded. Wrap it in a retry loop with backoff; the command is
idempotent so re-issuing is safe.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
'az webapp config container set' consistently returns a GatewayTimeout from
Microsoft.Web even though the ARM update is applied server-side, so blind
retries keep failing. Issue the set (tolerating the timeout) and poll
'az webapp config container show' to confirm the new image tag was applied,
only treating the deploy as failed if verification never succeeds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft JoshLove-msft added this pull request to the merge queue Jun 29, 2026
Merged via the queue into microsoft:main with commit 8e8595f Jun 29, 2026
53 checks passed
@JoshLove-msft JoshLove-msft deleted the fix/optional-path-trailing-slash branch June 29, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp eng

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants