Skip to content

fix(http-client-csharp): clear diagnostic when client namespace cannot be resolved#10915

Merged
JoshLove-msft merged 2 commits into
microsoft:mainfrom
JoshLove-msft:joshlove-msft/playground-namespace-deserialization-diagnostics
Jun 9, 2026
Merged

fix(http-client-csharp): clear diagnostic when client namespace cannot be resolved#10915
JoshLove-msft merged 2 commits into
microsoft:mainfrom
JoshLove-msft:joshlove-msft/playground-namespace-deserialization-diagnostics

Conversation

@JoshLove-msft

@JoshLove-msft JoshLove-msft commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Problem

The C# playground server intermittently returned 500 from POST /generate with an opaque generator error:

The JSON value could not be converted to Microsoft.TypeSpec.Generator.Input.InputNamespace. Path: $ | LineNumber: 6 | BytePositionInLine: 1.

The root code model had a null name. createModel set name: getClientNamespaceString(sdkContext)! — the non-null assertion let undefined through, JSON.stringify dropped the property, and the nameless code model failed to deserialize in the generator with a message that gave no clue what was wrong.

Why it was intermittent

The playground recompiles on every debounced keystroke and POSTs the code model to the server. The emitter only guards on !program.hasError() — but a spec with a plain namespace and no @service compiles with zero errors (verified locally):

spec resolved namespace program.hasError()
@service namespace (versioned or not) "Foo" false
plain namespace Foo; (no @service) undefined false
no namespace at all undefined false

So while typing — before @service is added or mid-edit — the buffer is momentarily valid but service-less, and that error-free tick POSTs a nameless model → 500. A moment later the spec has @service and it works. It was never the same final spec failing, and never the server corrupting anything.

Fix

  • Emitter: when the client namespace cannot be resolved, report a clear unresolved-client-namespace diagnostic and skip generation instead of sending a nameless code model. (client-model-builder.ts, emitter.ts, lib.ts)
  • Generator: replace the bare throw new JsonException() in InputNamespaceConverter with a descriptive message naming the missing name property (defense in depth).
  • Playground server: add a root GET / route returning 200 to silence Azure App Service availability-probe 404s.

Tests

  • New emitter test asserting the unresolved-client-namespace diagnostic is reported and the code model name is empty.
  • New generator test asserting the descriptive deserialization error.
  • Full emitter suite (227 passed) and Input generator suite pass.

Fixes #10914

…mespace deserialization failures

The playground server intermittently returns 500s when the generator fails to
deserialize the root InputNamespace with the opaque message "The JSON value
could not be converted to InputNamespace" (name was null). Because parsing a
fixed document is deterministic, non-deterministic failures for a spec that
always declares a namespace indicate the code model is being mangled/truncated
before it reaches the generator.

This adds the diagnostics needed to localize the corruption and makes the
failure self-explanatory:

- Generator: replace the bare `throw new JsonException()` in
  InputNamespaceConverter with a descriptive message that names the missing
  'name' property, while preserving the System.Text.Json Path/line/byte info.
- Playground server: log a SHA-256 of the received code model so identical
  specs that yield different hashes (transport mangling) become visible, and
  add a write-integrity check that flags when the code model written to disk
  differs from the received payload (server-side mangling).

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 6, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 6, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: ab4c109

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

…ce cannot be resolved

When the emitter could not resolve a namespace, it produced a code model with
no `name` and still sent it to the generator, which failed with an opaque
root-level deserialization error (a 500 on the playground server). Report an
actionable `unresolved-client-namespace` diagnostic and skip generation
instead. Also remove the pointless server-side write-integrity check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft JoshLove-msft changed the title fix(http-client-csharp): diagnostics for intermittent root InputNamespace deserialization failures fix(http-client-csharp): clear diagnostic when client namespace cannot be resolved Jun 6, 2026
Comment thread packages/http-client-csharp/emitter/src/lib/client-model-builder.ts
@JoshLove-msft JoshLove-msft added this pull request to the merge queue Jun 9, 2026
Merged via the queue into microsoft:main with commit b248d66 Jun 9, 2026
29 checks passed
@JoshLove-msft JoshLove-msft deleted the joshlove-msft/playground-namespace-deserialization-diagnostics branch June 9, 2026 01:00
JennyPng pushed a commit to JennyPng/typespec that referenced this pull request Jun 10, 2026
…t be resolved (microsoft#10915)

## Problem

The C# playground server intermittently returned **500** from `POST
/generate` with an opaque generator error:

> The JSON value could not be converted to
Microsoft.TypeSpec.Generator.Input.InputNamespace. Path: \$ |
LineNumber: 6 | BytePositionInLine: 1.

The root code model had a `null` `name`. `createModel` set `name:
getClientNamespaceString(sdkContext)!` — the non-null assertion let
`undefined` through, `JSON.stringify` dropped the property, and the
nameless code model failed to deserialize in the generator with a
message that gave no clue what was wrong.

## Why it was intermittent

The playground recompiles on every debounced keystroke and POSTs the
code model to the server. The emitter only guards on
`!program.hasError()` — but **a spec with a plain `namespace` and no
`@service` compiles with zero errors** (verified locally):

| spec | resolved namespace | `program.hasError()` |
|---|---|---|
| `@service` namespace (versioned or not) | `"Foo"` | false |
| plain `namespace Foo;` (no `@service`) | `undefined` | **false** |
| no namespace at all | `undefined` | false |

So while typing — before `@service` is added or mid-edit — the buffer is
momentarily *valid but service-less*, and that error-free tick POSTs a
nameless model → 500. A moment later the spec has `@service` and it
works. It was never the same final spec failing, and never the server
corrupting anything.

## Fix

- **Emitter:** when the client namespace cannot be resolved, report a
clear `unresolved-client-namespace` diagnostic and **skip generation**
instead of sending a nameless code model. (`client-model-builder.ts`,
`emitter.ts`, `lib.ts`)
- **Generator:** replace the bare `throw new JsonException()` in
`InputNamespaceConverter` with a descriptive message naming the missing
`name` property (defense in depth).
- **Playground server:** add a root `GET /` route returning 200 to
silence Azure App Service availability-probe 404s.

## Tests

- New emitter test asserting the `unresolved-client-namespace`
diagnostic is reported and the code model name is empty.
- New generator test asserting the descriptive deserialization error.
- Full emitter suite (227 passed) and Input generator suite pass.

Fixes microsoft#10914

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C# playground server: intermittent 500 from non-deterministic root InputNamespace deserialization (name missing / mangled code model)

2 participants