Skip to content

fix(openapi3): apply @encode to the inner type of nullable properties in OpenAPI 3.1 and 3.2 - #12016

Open
om singhal (Om-singhaI) wants to merge 1 commit into
microsoft:mainfrom
Om-singhaI:fix/openapi3-encode-nullable-property
Open

om singhal (Om-singhaI) wants to merge 1 commit into
microsoft:mainfrom
Om-singhaI:fix/openapi3-encode-nullable-property

Conversation

@Om-singhaI

Copy link
Copy Markdown
Contributor

Fixes #12015

In OpenAPI 3.1 and 3.2, T | null is emitted as anyOf: [T, { type: "null" }]. applyEncoding ran on that wrapper, so the encoded type and format landed next to anyOf while T kept its original type. The schema then rejected null, and for unixTimestamp, seconds and @encode(string) it matched nothing at all. bytes | null also got format where it should get contentEncoding.

3.0 isn't affected because it flattens T | null into one schema with nullable: true.

Changes

  • In openapi-helpers-3-1.ts, when the property has @encode and the schema is anyOf: [T, { type: "null" }], the encoding goes on T and the null member is left alone. Properties and parameters both use this helper.
  • getEncodingFieldName looks through T | null so bytes | null keeps contentEncoding.
  • Added a changeset.

Testing

  • New worksFor(["3.1.0", "3.2.0"]) cases in nullable-properties.test.ts for unixTimestamp, rfc7231, seconds, @encode(string) on int64, base64url bytes and a nullable query parameter. All 12 fail on main and pass with the fix.
  • Ran 10 related test files in packages/openapi3/test (primitive types, unions, arrays, parameters, examples and others): 1222 passed.
  • Checked the new 3.1 output with Ajv (draft 2020): the encoded value and null both pass. 3.0 output is unchanged.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped, includes regression tests for the new branch behavior, and provides an appropriate fix changeset for the user-visible emitter output correction.

Pull request overview

Fixes OpenAPI 3.1/3.2 emission for @encode applied to nullable unions (T | null) by ensuring encoding is applied to the non-null schema inside anyOf, matching the intended JSON Schema semantics and avoiding schemas that reject null (or all values for type-changing encodes).

Changes:

  • Apply @encode to the non-null member of anyOf: [T, { type: "null" }] in the 3.1 helper so null remains valid and encoded types/formats land in the right place.
  • Update encoding-field selection to look through nullable unions so bytes | null correctly uses contentEncoding instead of format.
  • Add targeted tests for OpenAPI 3.1.0 and 3.2.0, plus a Chronus fix changeset for @typespec/openapi3.
File summaries
File Description
packages/openapi3/src/openapi-helpers-3-1.ts Applies encoding to the non-null anyOf member for nullable unions and fixes encoding field selection for nullable bytes.
packages/openapi3/test/nullable-properties.test.ts Adds regression tests covering nullable properties/parameters with @encode for OpenAPI 3.1.0 and 3.2.0.
.chronus/changes/fix-openapi3-encode-nullable-property-2026-09-18.md Adds a fix changeset documenting the user-visible behavior correction in @typespec/openapi3.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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

Labels

emitter:openapi3 Issues for @typespec/openapi3 emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: @encode on a nullable property emits a schema that rejects null in OpenAPI 3.1 and 3.2

2 participants