Skip to content

fix ICE in serializeValueAsJson#9804

Merged
markcowl merged 12 commits intomainfrom
copilot/fix-ice-serialize-value-json
Mar 4, 2026
Merged

fix ICE in serializeValueAsJson#9804
markcowl merged 12 commits intomainfrom
copilot/fix-ice-serialize-value-json

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

  • Add test for known scalar constructors as ModelProperty default values in openapi3
  • Fix serializeValueAsJson to return undefined for unrecognized scalar constructors
  • Remove inadvertent csharp emitter file changes (reverted to pre-PR state)
Original prompt

This section details on the original issue you should resolve

<issue_title>[core] ICE in serializeValueAsJson</issue_title>
<issue_description>### Describe the bug

The core library throws an uncaught Error on a custom scalar initializer with no arguments in serializeValueAsJson. The Error is provoked by the OpenAPI3 emitter (as well as the JSON Schema emitter) and bubbles back up to the emitter entrypoint where it triggers an ICE.

The logic attempts to use the first argument of the initializer, which isn't reliable. That logic works for "cast-like" scalar values (e.g. uuid("...")), but not for initializers (e.g. uuid.random() // no first argument!).

Reproduction

scalar S {
  init i();
}

model M { p: S = S.i(); }

https://typespec.io/playground/?e=%40typespec%2Fopenapi3&c=c2NhbGFyIFMgewogIGluaXQgaSgpOwp9Cgptb2RlbCBNIHsgcDogUyA9IFMuxBsgfQ%3D%3D&options=%7B%7D&vs=%7B%7D

However, if you provide a first argument, this is enough to quell the ICE but the emit is still wrong:

scalar S {
  init i(s: string);
}

// Default value renders as "foo", which is wrong.
model M { p: S = S.i("foo") }

https://typespec.io/playground/?e=%40typespec%2Fopenapi3&c=c2NhbGFyIFMgewogIGluaXQgaShzOiBzdHJpbmcpOwp9Cgptb2RlbCBNIHsgcDogUyA9IFMuaSgiZm9vIik7IH0%3D&options=%7B%7D&vs=%7B%7D

Checklist

<agent_instructions>Instead we should drop the result if we don't recognize the constructor</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@timotheeguerin Drop the result like we do with `now()` if we can't resolve the scalar constructor

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…n serializeValueAsJson

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ICE in serializeValueAsJson for custom scalars fix(compiler): avoid ICE in serializeValueAsJson for unrecognized scalar constructors Feb 25, 2026
@microsoft-github-policy-service microsoft-github-policy-service bot added the compiler:core Issues for @typespec/compiler label Feb 25, 2026
@markcowl
Copy link
Contributor

@copilot This fix is overbroad, causing 3 tests that use known scalars to fail. Please ensure that all tests are passing. Also, please add a test that checks the openapi3 serialization of a default value for a model property, similar to the one shown in the repro.

…reserve args[0] behavior

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 26, 2026

@copilot This fix is overbroad, causing 3 tests that use known scalars to fail. Please ensure that all tests are passing. Also, please add a test that checks the openapi3 serializat...

Fixed in e2f42d9. The previous fix was too broad — it dropped undefined for all unrecognized scalar constructors, breaking the existing shortName.name("Shorty") → "Shorty" behavior.

The correct fix only returns undefined when args[0] is missing (the no-arg case that caused the ICE), and preserves the original args[0] serialization for scalars with arguments.

Also added the openapi3 test that checks scalar S { init i(); } / model M { p: S = S.i(); } doesn't crash and produces no default value.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/astro.js build sh s/.b�� tspd --enable-experimental gen-e--llmstxt sh pec/node_modules/.bin/sh ental ture n-schema/referengenerate-scenarios-summary sh -c astro check --minimumFailingSeverity hint &amp;&amp; ast--filter node node_modules/.bin/tspd . sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:openapi3 Issues for @typespec/openapi3 emitter label Feb 26, 2026
Copilot AI changed the title fix(compiler): avoid ICE in serializeValueAsJson for unrecognized scalar constructors fix(compiler): avoid ICE in serializeValueAsJson for no-argument scalar constructors Feb 26, 2026
@markcowl
Copy link
Contributor

markcowl commented Mar 3, 2026

@copilot if the scalar is not a known scalar, the first argument to its constructor should not be used to define the default value (or the example value). There is no way to represent the value returned from a scalar constructor, unless the scalar constructor is from a known scalar type. To validate this fix, create a test in which a scalar that extends no other scalar defines a constructor with a string type argument. Validate that when an application of this constructor is used in an example, or as a default value, that the resulting value is undefined and there is no diagnostic emitted.

@markcowl
Copy link
Contributor

markcowl commented Mar 3, 2026

@copilot Please pull in the latest changes, update dependencies and validate that all ci checks pass.

…ors in serializeValueAsJson

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot if the scalar is not a known scalar, the first argument to its constructor should not be used to define the default value (or the example value). There is no way to repre...

Fixed in d3d86c9. serializeScalarValueAsJson now returns undefined for all unrecognized scalar constructors regardless of their arguments — there's no way to represent the value of a custom scalar constructor.

The existing openapi3 test that expected "Shorty" from shortName.name("Shorty") was updated to expect undefined, and both the no-arg case (S.i()) and with-arg case (shortName.name("Shorty")) are covered. No diagnostic is emitted in either case.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/astro.js build sh s/.b�� ../../website/sr--llmstxt sh de pespec-library ture .0/bin/sh sh k/ty�� astro check --minimumFailingSeverity hint &amp;&amp; ast--filter sh 1/x64/lib/node_modules/.bin/sh . node t/node_modules/.doc sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title fix(compiler): avoid ICE in serializeValueAsJson for no-argument scalar constructors fix(compiler): avoid ICE in serializeValueAsJson for unrecognized scalar constructors Mar 3, 2026
@markcowl
Copy link
Contributor

markcowl commented Mar 3, 2026

@copilot your branch is still out of date with the base branch (main) please pull the latest changes, reinstall, rebuild, and update the pr

Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot Please pull in the latest changes, update dependencies and validate that all ci checks pass.

Done in b62632b. Merged latest main, ran pnpm install, verified all checks pass locally:

  • Format check: ✅
  • Lint: ✅
  • Compiler tests: 3800/3800 ✅
  • OpenAPI3 tests: 2466/2466 ✅

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/astro.js build uname s/.b�� os dotnet _modules/.bin/node /library-linter node ture reams/reference node sion�� sc -p ./tsconfig.build.json gen-extern-signature node_modules/.bin/tspd r --no-emit ture rsioning/referendoc sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot your branch is still out of date with the base branch (main) please pull the latest changes, reinstall, rebuild, and update the pr

The branch is already up to date with main — commit b62632b (from the previous session) merged all of main's commits. git log main ^HEAD returns empty, confirming no commits in main are missing from this branch. All CI checks (format, lint, compiler tests 3800/3800, openapi3 tests 2466/2466) are passing locally.

@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 Mar 3, 2026
@markcowl
Copy link
Contributor

markcowl commented Mar 3, 2026

@copilot your merge creataed problems in this PR - this PR is now changing several files in the csharp emitter project inadvertently. Please rebase your changes on the tip of the main branch and ensure that no file changes you didn't need for your fix are included

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot your merge creataed problems in this PR - this PR is now changing several files in the csharp emitter project inadvertently. Please rebase your changes on the tip of the ma...

Fixed in c6d28ef. The inadvertent csharp file changes from the previous merge commit have been reverted. The PR now only touches the 4 files it should: the compiler fix (examples.ts), its tests (examples.test.ts), the openapi3 test (models.test.ts), and the changeset file.

@markcowl markcowl removed the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Mar 3, 2026
@markcowl markcowl changed the title test(openapi3): add test for known scalar constructors as ModelProperty default values fix ICE in serializeValueAsJson Mar 3, 2026
@markcowl markcowl marked this pull request as ready for review March 3, 2026 22:39
@markcowl
Copy link
Contributor

markcowl commented Mar 4, 2026

/azp run typespec - PR Tools

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

…-2026-2-25-20-0-0.md

Co-authored-by: Timothee Guerin <tiguerin@microsoft.com>
@markcowl markcowl enabled auto-merge March 4, 2026 20:12
@markcowl markcowl added this pull request to the merge queue Mar 4, 2026
Merged via the queue into main with commit 886727c Mar 4, 2026
24 checks passed
@markcowl markcowl deleted the copilot/fix-ice-serialize-value-json branch March 4, 2026 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler:core Issues for @typespec/compiler emitter:openapi3 Issues for @typespec/openapi3 emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[core] ICE in serializeValueAsJson

4 participants