Skip to content

fix: name the rule when a configurable rule is missing its assertions block - #3040

Open
luantaraschi wants to merge 1 commit into
Redocly:mainfrom
luantaraschi:fix/configurable-rule-missing-assertions
Open

fix: name the rule when a configurable rule is missing its assertions block#3040
luantaraschi wants to merge 1 commit into
Redocly:mainfrom
luantaraschi:fix/configurable-rule-missing-assertions

Conversation

@luantaraschi

@luantaraschi luantaraschi commented Aug 17, 2026

Copy link
Copy Markdown

What/Why/How?

A configurable rule declared without its assertions block dies with a message that says nothing about the config:

Something went wrong when processing openapi.yaml:

  - Cannot read properties of undefined (reading 'pattern')

getAssertsToApply reads assertion.assertions[assertName] for the first key of asserts, which is pattern, so that is where the undefined surfaces.

The config schema already declares the block as mandatory. ConfigurableRule and Where in packages/core/src/types/redocly-yaml.ts both carry required: ['subject', 'assertions'], so no valid configuration is being turned away here. The runtime simply was not checking what the schema promises, and redocly lint still ran the rule after the config struct warning.

The change adds that check next to the 'type' (String) is required guards that were already there, in the four places a configurable rule definition gets built:

  • rules/common/assertions/index.ts, the rule itself
  • rules/common/assertions/utils.ts, each where entry
  • graphql/assertions.ts, both of the same two spots

The GraphQL path keeps its own if (!kind) continue, so a rule with no subject type is still skipped rather than rejected. Only the missing assertions block now raises, which is what the OpenAPI path already did.

After:

Something went wrong when processing openapi.yaml:

  - rule/test: 'assertions' (Object) is required

Reference

Closes #2185.

Testing

Two unit tests in packages/core/src/rules/common/assertions/__tests__/index.test.ts for the rule and its where entry, and two in packages/core/src/rules/graphql/__tests__/assertions.test.ts that go through lintFromString against a schema. All four fail on main with the Cannot read properties of undefined message.

VITEST_SUITE=unit npx vitest run packages/core/src/rules/common/assertions packages/core/src/rules/graphql

The whole packages/core suite was run on main and on this branch back to back, on Windows with Node 22.20. main gives 36 failed and 1015 passed, the branch gives 36 failed and 1019 passed, so the only difference is the four tests added here. Those 36 are pre-existing path and snapshot mismatches on Windows and none of them touch assertions.

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 docs already describe assertions as part of the rule shape, so nothing there changes.

Security

  • The security impact of the change has been considered The change only turns an unhandled TypeError into a named error before any document is read.
  • Code follows company security practices and guidelines

Note

Low Risk
Small defensive validation that replaces an obscure TypeError with explicit config errors; no change to valid rule behavior.

Overview
Adds runtime validation so configurable rules without an assertions object fail with a clear, rule-named error instead of Cannot read properties of undefined (reading 'pattern').

The check mirrors existing 'type' (String) is required guards in the OpenAPI path (Assertions and each where entry in buildVisitorObject) and the GraphQL path (GraphqlAssertions and buildWhereMatchers). Invalid configs are rejected before getAssertsToApply touches assertion.assertions.

Unit and integration tests cover missing assertions on the rule and on where entries for both stacks; a patch changeset documents the fix.

Reviewed by Cursor Bugbot for commit 57731ab. Bugbot is set up for automated code reviews on this repo. Configure here.

@luantaraschi
luantaraschi requested review from a team as code owners August 17, 2026 16:51
@changeset-bot

changeset-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 57731ab

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

@tatomyr

tatomyr commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the contribution, @luantaraschi. Frankly, I'd prefer to silently skip incorrectly configured rules rather than throw an error, since there's already a lint check for the configuration itself that should flag the problem to the user. What do you think?

@luantaraschi

Copy link
Copy Markdown
Author

That works for me on the CLI side, where lintConfig runs first and already reports The field 'assertions' must be present on this level.

The case I would flag is the programmatic one. createConfig on its own neither throws nor reports anything, and lintFromString does not run the config check, so with a silent skip a rule missing assertions would simply do nothing and the caller would get no signal at all.

There is also the sibling guard a few lines above: a missing subject.type throws 'type' (String) is required rather than skipping. If misconfigured rules should be skipped, that one probably wants the same treatment, otherwise the same class of mistake behaves in two different ways.

I am happy to switch this to skipping either way, with or without the type guard following. Just say which you prefer.

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.

Configurable rule fails with unclear error message

2 participants