Skip to content

Schemas are silently dropped when quoted YAML examples contain high-precision numbers #233

Description

@atacan

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions