Skip to content

fix: resolve default values from emitter options JSON schema#9971

Draft
Copilot wants to merge 9 commits intomainfrom
copilot/fix-emitter-options-defaults
Draft

fix: resolve default values from emitter options JSON schema#9971
Copilot wants to merge 9 commits intomainfrom
copilot/fix-emitter-options-defaults

Conversation

Copy link
Contributor

Copilot AI commented Mar 9, 2026

Minimal fix — only 4 files changed, no breaking changes to existing tests.

Changes Made

  • schema-validator.ts: Add useDefaults option to JSONSchemaValidatorOptions interface and pass it through to AJV (+2 lines)
  • library.ts: Enable useDefaults: true when creating the emitter option validator (+1 line)
  • emitter-options.test.ts: Add 3 test cases for schema defaults — applies defaults when no options provided, user values override defaults, and partial defaults for missing options (+76 lines)
  • Changelog entry: Documents the fix for @typespec/compiler

How It Works

The fix enables AJV's built-in useDefaults option specifically for the emitter option validator. When an emitter defines default values in its JSON schema options, those defaults are now applied to context.options during $onEmit. This is a non-breaking, additive change — existing emitters without default values in their schemas are unaffected.

Testing

  • ✅ All 8 emitter options tests pass (1 pre-existing skip)
  • ✅ No changes to any existing tests required
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: EmitterOptions defaults are not resolved.</issue_title>
<issue_description>### Describe the bug

Following the same example of custom configs definitions from here: https://typespec.io/docs/extending-typespec/emitters-basics/#custom-configuration-options, but using default for some property, doesn't in runtime doesn't result in default value being passed into emitter, so the typing is off.

Reproduction

E.g. having this from documentation:

export interface EmitterOptions {
  "target-name": string;
}

const EmitterOptionsSchema: JSONSchemaType<EmitterOptions> = {
  type: "object",
  additionalProperties: false,
  properties: {
    "target-name": { type: "string", nullable: true, default: null },
  },
  required: [],
};

In emitter

export const $lib = createTypeSpecLibrary({
  internal: internalLib,
  emitter: {
    options: EmitterOptionsSchema,
  },
});

export async function $onEmit(context: EmitContext<EmitterOptions>) {
  console.log(contenxt.options); // --> {}
}

If I'm providing json-schema, I'd expect defaults set in it to be used. Otherwise it doesn't make a lot of sense and usage of json-schema in this case should be documented on the terms of scopes it's being applied for. R.n. seems like only for IDE autocomplete integration for emitters, but no types validation nor defaults substitution.

Checklist

<agent_instructions>Find any issues in the backlog that address this deficiency</agent_instructions>

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

@markcowl @markcowl see if any duplicate issues

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the compiler:core Issues for @typespec/compiler label Mar 9, 2026
Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix EmitterOptions defaults not being resolved fix: resolve default values from emitter options JSON schema Mar 9, 2026
Copilot AI and others added 2 commits March 16, 2026 19:35
Merge latest main and reapply changes cleanly. Added useDefaults option
to JSONSchemaValidatorOptions and enabled it for emitter option validation.
Added tests for schema default values.

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:java Issue for the Java client emitter: @typespec/http-client-java label Mar 16, 2026
Copilot AI requested a review from markcowl March 16, 2026 19:39
@markcowl
Copy link
Contributor

@copilot Please pull the latest and fix merge conflicts therre are far too many changes in this PR

…th bytes in multipart body (#10046)

- [x] Analyze root cause of "Duplicate type name" error for multipart
union with bytes
- [x] Fix `addUsagesInOperation` in `visibility-usage.ts` to traverse
multipart body part types
- [x] Add test case for union with bytes in multipart body
- [x] Add changelog entry
- [x] Build and test changes (all 2482 tests pass)
- [x] Apply prettier formatting

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>OpenAPI emitter fails on union with bytes for
multipart</issue_title>
> <issue_description>The following definition
> 
> ```tsp
> import "@typespec/http";
> using Http;
> 
> union CreateVideoMultipartBodyInputReference {
>   bytes,
>   ImageRefParam,
> }
> union ImageRefParam {
>   {
>     @maxlength(20971520)
>     image_url: url,
>   },
>   {
>     file_id: string,
>   },
> }
> model CreateVideoMultipartBody {
> 
>   input_reference?: HttpPart<CreateVideoMultipartBodyInputReference>;
> }
> 
> op createVideo(
>   @Header
>   contentType: "multipart/form-data",
> 
>   @multipartBody
>   body: CreateVideoMultipartBody,
> ): void;
> ```
> 
> Fails with this error message : Duplicate type name:
'CreateVideoMultipartBodyInputReference'. Check @FriendlyName decorators
and overlap with types in TypeSpec or service namespace.
> 
> Interestingly, if we replace bytes by string or something else, the
emission starts working. I'd expect it to work with bytes as well.
> </issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #10045

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Send tasks to Copilot coding agent from
[Slack](https://gh.io/cca-slack-docs) and
[Teams](https://gh.io/cca-teams-docs) to turn conversations into code.
Copilot posts an update in your thread when it's finished.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:openapi3 Issues for @typespec/openapi3 emitter label Mar 16, 2026
Copilot AI and others added 3 commits March 16, 2026 22:25
Enable useDefaults in AJV for the emitter option validator so that
default values defined in the JSON schema are applied to context.options.

Fixes #8489
Remove files that were accidentally included via a merge commit.
Only the emitter options defaults fix should be in this PR.

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Remove remaining C# generator files that were accidentally changed
from the original branch merge.

Co-authored-by: markcowl <1054056+markcowl@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 Mar 16, 2026
Copy link
Contributor Author

Copilot AI commented Mar 16, 2026

@copilot Please pull the latest and fix merge conflicts therre are far too many changes in this PR

Pulled latest main and cleaned up the branch. Removed all unrelated files that were accidentally included via the merge commit. The PR diff is now just 4 files with 86 insertions (commits 40e0fa0c, 77b4692b, 3f97f319):

  • schema-validator.ts: Add useDefaults option
  • library.ts: Enable useDefaults: true for emitter options
  • emitter-options.test.ts: Tests for defaults
  • Changelog entry

Note: GitHub may still show some C# files in the diff because the PR's merge-base hasn't caught up to latest main yet, but those files are identical between the branch and main HEAD.

@markcowl
Copy link
Contributor

@copilot Try to find a way to fix this issue without requiring a breaking change across all these tests

Copy link
Contributor Author

Copilot AI commented Mar 16, 2026

@copilot Try to find a way to fix this issue without requiring a breaking change across all these tests

The fix itself is minimal and non-breaking — only 4 files are actually changed:

  1. schema-validator.ts — add useDefaults option (+2 lines)
  2. library.ts — enable useDefaults: true (+1 line)
  3. emitter-options.test.ts — 3 new test cases (+76 lines)
  4. Changelog entry (+7 lines)

No C# tests are modified by this fix. The C# and openapi3 files visible in GitHub's PR diff are artifacts from the merge history — they are byte-for-byte identical to current main at the branch tip. The useDefaults AJV option only affects emitter option validation and doesn't touch any other validators.

I wasn't able to force-push a clean rebase through the available tooling. The branch may need a manual git rebase --onto origin/main and force push to clean up the history so GitHub shows only the 4 actual files.

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:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp emitter:client:java Issue for the Java client emitter: @typespec/http-client-java emitter:openapi3 Issues for @typespec/openapi3 emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: EmitterOptions defaults are not resolved.

2 participants