Skip to content

fix(no-enum-type-mismatch): report every value when type is an array - #3050

Open
luantaraschi wants to merge 1 commit into
Redocly:mainfrom
luantaraschi:fix/enum-type-mismatch-array-type
Open

fix(no-enum-type-mismatch): report every value when type is an array#3050
luantaraschi wants to merge 1 commit into
Redocly:mainfrom
luantaraschi:fix/enum-type-mismatch-array-type

Conversation

@luantaraschi

@luantaraschi luantaraschi commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

When type is written as an array, no-enum-type-mismatch drops violations and points at an index that does not exist.

openapi: 3.1.0
# ...
schema:
  type:
    - string
  enum:
    - 1
    - '1'

redocly lint says the description is valid. Writing the same constraint as type: string reports the number, so the array form loses it. It is not about single element arrays either: type: [string, boolean] with the same enum is also silent.

The second symptom shows up as soon as the offending value is not a string:

schema:
  type:
    - boolean
  enum:
    - zz
    - 2

Both are reported, but 2 comes out first at pointer .../schema/enum/-1, before zz at enum/0. That pointer goes out through lint -f json, --format=checkstyle and --generate-ignore-file, and getAstNodeByPointer does items[parseInt('-1', 10)], gets undefined and breaks, so the codeframe underlines the whole enum sequence instead of the entry.

Both come from the accumulator in the array branch being keyed by the enum value:

const mismatchedResults: { [key: string]: string[] } = {};
for (const enumValue of schema.enum) {
  mismatchedResults[enumValue] = [];

Object keys are strings, so 1 and '1' land on "1". The second pass resets the entry, the string passes, and the delete then removes the report the number had earned. The location does schema.enum.indexOf(mismatchedKey) with a key that came back out of Object.keys, so it is always a string: [2].indexOf('2') is -1. Object.keys also hoists integer-like keys, which is why the order flips.

The scalar branch right above already does it the plain way, iterating the values and reporting each one. I made the array branch do the same and drop the accumulator: for each value in order, report it when it matches none of the listed types. The message and the reference are unchanged.

Two tests, one per symptom, both failing on main: the first returns [] there, the second returns 2 at enum/-1 before zz at enum/0.

vitest run packages/core gives the same 34 failures before and after (they are pre-existing here, mostly config and component-name suites), with 1037 passing before and 1039 after. oxlint reports nothing on the rule and oxfmt --check is clean on all three files. Changeset added.

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

The rule's documentation page already describes the behaviour this restores, so I did not change it. It says the rule requires every enum value to conform to the schema's type, and lists OAS 3.1 as supported.

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

Nothing here reads input in a new way. The rule looks at the same schema.enum and schema.type it always did; what changes is that a value is no longer able to hide behind another one that shares its string form. If anything the linter now reports strictly more, which is the safer direction for a validation rule.

The array-type branch collected its results in an object keyed by the enum
value. Object keys are strings, so 1 and '1' shared a key and the report
earned by the number was deleted when the string passed. The location then
looked the key up with indexOf against the original array, which returns
-1 for anything that is not a string, so non-string values were reported at
a pointer that does not exist and Object.keys put them out of document
order on the way.

Walk the values with their index and report the ones that match none of the
listed types, the way the scalar branch above already does.
@luantaraschi
luantaraschi requested review from a team as code owners August 23, 2026 05:13
@changeset-bot

changeset-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9bdf0be

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@redocly/openapi-core Patch
@redocly/cli Patch
@redocly/client-generator Patch
@redocly/respect-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Performance Benchmark (Lower is Faster)

CLI Version Bundle Lint Check Config
cli-latest ▓ 1.00x (Fastest) ▓ 1.00x ± 0.01 ▓ 1.00x (Fastest)
cli-next ▓ 1.02x ± 0.01 ▓ 1.00x (Fastest) ▓▓ 1.04x ± 0.01

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant