Reproduction: https://github.com/atacan/discussion-openapi-format-schema-drop-repro
I asked AI to write a detailed description:
Description
openapi-format can silently remove the schema following a quoted YAML scalar that contains a high-precision number.
The command exits successfully and reports that the document was formatted, despite the resulting OpenAPI document losing schemas.
Minimal reproduction
Create input.yaml:
openapi: 3.1.0
info:
title: Reproduction
version: 1.0.0
paths: {}
components:
schemas:
Before:
type: object
example: "{\n \"score\": 0.8189693396524255,\n}"
CreateResponse:
type: object
properties:
id:
type: string
Run:
openapi-format --no-sort input.yaml -o output.yaml
The command reports success, but CreateResponse is absent from output.yaml.
The issue also occurs with --no-bundle:
openapi-format --no-sort --no-bundle input.yaml -o output.yaml
Expected behavior
Both schemas should remain in the output:
components:
schemas:
Before:
# ...
CreateResponse:
# ...
Actual behavior
Only Before remains. The following CreateResponse mapping is silently dropped.
Suspected root cause
parseString() calls encodeLargeNumbers() on the raw document before parsing the YAML.
encodeLargeNumbers() applies this regular expression to the entire input:
/: ([0-9]+(\.[0-9]+)?)\b(?!\.[0-9])(,|\n)/g
For sufficiently precise numbers, it replaces the match with:
`: "${number}==="${endChar}`
The regex is unaware of YAML scalar boundaries. It therefore also matches numbers inside quoted strings, such as the escaped JSON example above.
Conceptually, this:
example: "{\n \"score\": 0.8189693396524255,\n}"
is changed before parsing to something resembling:
example: "{\n \"score\": "0.8189693396524255===",\n}"
The inserted quotes are not escaped for the surrounding YAML string. This corrupts the parsed mapping and causes the following schema to disappear without an error.
Parsing the same reproduction directly with @stoplight/yaml preserves both keys. Parsing it through openapi-format produces:
Direct YAML parser keys: [Before, CreateResponse]
openapi-format keys: [Before]
Impact
This causes silent, destructive data loss in valid OpenAPI documents. Large specifications can lose multiple unrelated schemas depending on where quoted examples containing high-precision numbers occur.
Because the CLI exits successfully, downstream code generation may proceed with an incomplete document.
Suggested fix
Avoid applying number transformations to the raw YAML text. Parse the document first and traverse actual numeric values, leaving string values untouched.
A regression test containing a quoted JSON example followed by another component schema would also catch this case.
Environment
openapi-format: 1.27.1
- Node.js: 22.23.1
- OS: macOS
- OpenAPI: 3.1.0
Reproduction: https://github.com/atacan/discussion-openapi-format-schema-drop-repro
I asked AI to write a detailed description:
Description
openapi-formatcan silently remove the schema following a quoted YAML scalar that contains a high-precision number.The command exits successfully and reports that the document was formatted, despite the resulting OpenAPI document losing schemas.
Minimal reproduction
Create
input.yaml:Run:
The command reports success, but
CreateResponseis absent fromoutput.yaml.The issue also occurs with
--no-bundle:Expected behavior
Both schemas should remain in the output:
Actual behavior
Only
Beforeremains. The followingCreateResponsemapping is silently dropped.Suspected root cause
parseString()callsencodeLargeNumbers()on the raw document before parsing the YAML.encodeLargeNumbers()applies this regular expression to the entire input:/: ([0-9]+(\.[0-9]+)?)\b(?!\.[0-9])(,|\n)/gFor sufficiently precise numbers, it replaces the match with:
`: "${number}==="${endChar}`The regex is unaware of YAML scalar boundaries. It therefore also matches numbers inside quoted strings, such as the escaped JSON example above.
Conceptually, this:
is changed before parsing to something resembling:
The inserted quotes are not escaped for the surrounding YAML string. This corrupts the parsed mapping and causes the following schema to disappear without an error.
Parsing the same reproduction directly with
@stoplight/yamlpreserves both keys. Parsing it throughopenapi-formatproduces:Impact
This causes silent, destructive data loss in valid OpenAPI documents. Large specifications can lose multiple unrelated schemas depending on where quoted examples containing high-precision numbers occur.
Because the CLI exits successfully, downstream code generation may proceed with an incomplete document.
Suggested fix
Avoid applying number transformations to the raw YAML text. Parse the document first and traverse actual numeric values, leaving string values untouched.
A regression test containing a quoted JSON example followed by another component schema would also catch this case.
Environment
openapi-format: 1.27.1