Skip to content

feat: configurable operation-4xx-response (excludeMethods); add tests… - #3028

Open
jeremyfiel wants to merge 1 commit into
Redocly:mainfrom
jeremyfiel:fix/operation-4xx-skip-safe-methods
Open

feat: configurable operation-4xx-response (excludeMethods); add tests…#3028
jeremyfiel wants to merge 1 commit into
Redocly:mainfrom
jeremyfiel:fix/operation-4xx-skip-safe-methods

Conversation

@jeremyfiel

@jeremyfiel jeremyfiel commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What/Why/How?

What:

  • Run the operation-4xx-response validation at the Operation level so the HTTP method is available.
  • Add an excludeMethods rule option (case-insensitive array) to skip 4XX validation for specified HTTP methods.
  • Default excludeMethods to ["get", "head", "options"].
  • Mirror the same behavior for webhooks (honor existing validateWebhooks flag).
  • Add unit tests, documentation, and a changeset.

Why:

  • Safe/read-only methods commonly do not validate request bodies and often don't need a documented 4XX response. Requiring a 4XX response for every operation is noisy for many APIs. Making the excluded methods configurable lets projects relax the rule where appropriate without removing it globally.

How:

  • Move the 4XX check from the Responses visitor to Operation.leave so the HTTP verb (ctx.key) can be inspected.
  • If the operation method is in excludeMethods, skip validation.
  • Preserve reporting location to point at the operation.responses map (keeps tests/docs stable).
  • Provide a config example in docs to override excludeMethods.

Files changed (high level)

  • packages/core/src/rules/common/operation-4xx-response.ts — implementation and option parsing
  • packages/core/src/rules/common/tests/operation-4xx-response.exclude.test.ts — new unit tests for excluded/non-excluded methods
  • docs/@v2/rules/oas/operation-4xx-response.md — documented excludeMethods option and examples
  • .changeset/skip-4xx-safe-methods.md — changeset entry

Reference

  • Rule docs updated: docs/@v2/rules/oas/operation-4xx-response.md
  • Implementation: packages/core/src/rules/common/operation-4xx-response.ts
  • Branch: jeremyfiel/fix/operation-4xx-skip-safe-methods

Testing

Local verification steps (repo root):

  1. npm install
  2. npm run compile
  3. npm run unit
    • or to run only the new tests:
      npm run unit -- packages/core/src/rules/common/tests/operation-4xx-response.exclude.test.ts
  4. npm run lint

CI:

  • The PR will run the repository GitHub Actions (compile, unit tests, lint). The PR includes a changeset.

Screenshots (optional)

n/a

Check yourself

  • This PR follows the contributing guide: https://github.com/Redocly/redocly-cli/blob/main/CONTRIBUTING.md#pull-request-guidelines
  • All new/updated code is covered by tests (unit tests added)
  • 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 and included (docs/@v2 updated)
  • Changeset included (.changeset/skip-4xx-safe-methods.md)

Security

  • The security impact of the change has been considered. This is a linter/rules change and does not execute untrusted code or change runtime behavior of published packages.
  • Code follows company security practices and guidelines (no new dependencies added).

Note

Medium Risk
Default lint behavior changes for a common rule: GET/HEAD/OPTIONS no longer require documented 4XX responses unless users override excludeMethods, which may surprise teams on strict presets.

Overview
The operation-4xx-response rule now skips 4XX checks for configurable HTTP methods, with get, head, and options excluded by default. Validation runs at the Operation level (instead of on the responses map alone) so the verb is available; webhook operations follow the same rules when validateWebhooks is enabled. Lint locations still point at operation.responses.

Projects can extend exclusions via excludeMethods (documented with an example) or restore strict checks for every method by overriding that list (e.g. an empty array). Unit tests cover default exclusion for GET and enforcement for POST.

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

@jeremyfiel
jeremyfiel requested review from a team as code owners August 6, 2026 20:47
@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 17c84be

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

Comment thread packages/core/src/rules/common/operation-4xx-response.ts
Comment thread packages/core/src/rules/common/operation-2xx-response.ts
Comment thread packages/core/src/rules/common/.operation-2xx-response.fixnote.txt Outdated
@jeremyfiel
jeremyfiel force-pushed the fix/operation-4xx-skip-safe-methods branch from 89e3d99 to e4533ab Compare August 6, 2026 23:05

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e4533ab. Configure here.

Comment thread pnpm-lock.yaml Outdated
@jeremyfiel
jeremyfiel force-pushed the fix/operation-4xx-skip-safe-methods branch from e4533ab to 17c84be Compare August 6, 2026 23:09
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Performance Benchmark (Lower is Faster)

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

| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| severity | string | Possible values: `off`, `warn`, `error`. Default `warn` (in `recommended` configuration). |
| validateWebhooks | boolean | Determines if responses inside webhooks are validated. Default `false`. |
| excludeMethods | array | List of HTTP methods (case-insensitive) to exclude from 4XX validation. Default: `['get','head','options']` |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure if this should be the default. GET requests can still have 4xx responses like 401, 403, 429 which could be documented and the documentation could help consumers and code gen.

export const Operation4xxResponse: Oas3Rule | Oas2Rule = ({ validateWebhooks }) => {
export const Operation4xxResponse: Oas3Rule | Oas2Rule = (opts: any = {}) => {
const { validateWebhooks, excludeMethods: rawExcludeMethods } = opts || {};
const defaultExcluded = ['get', 'head', 'options'];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
const defaultExcluded = ['get', 'head', 'options'];
const defaultExcluded = ['options'];

I think I would start with this possibly.

Also, even this is a breaking change.

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.

2 participants