Skip to content

feat(apidocs): Add S034 lint for undocumented inline 4xx responses - #131072

Merged
BYK merged 2 commits into
masterfrom
lint/flake8-undocumented-4xx
Nov 13, 2026
Merged

BYK merged 2 commits into
masterfrom
lint/flake8-undocumented-4xx

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

#131067 had to add the 402 and 409 responses that the Seer Autofix start endpoint already returned but its @extend_schema(responses=...) never listed. Until then, @sentry/api typed those errors as unknown. This adds a flake8 rule, S034, that catches that kind of omission when the endpoint is written. Requested by @BYK after the review question on #131067.

What S034 checks: a class method with @extend_schema(responses={...}) that writes return Response(..., status=...) with a 4xx status, either a literal or a status.HTTP_4xx_* / HTTP_4xx_* name. If that status isn't a key in responses=, the rule fires. (status, media_type) tuple keys and digit-string keys count as documented. Run on the pre-#131067 version of group_ai_autofix.py, it flags all six of the 402/409 returns that PR documented.

What it doesn't check, as the rule's docstring says, so passing doesn't mean every 4xx is documented:

  • a 4xx that comes back from a helper, e.g. return handle_ui_feedback(...);
  • a response assigned to a variable before it's returned;
  • raised exceptions, which DRF renders as 4xx;
  • responses= values it can't read statically (a name, a ** spread, a non-literal key). The method is skipped rather than guessed at.

Two follow-ups would close the gaps the rule leaves: tightening the mypy plugin so error bodies are checked against their TypedDict (handled separately), and a test-time check of responses against the generated schema (#131073).

Existing violations: 95 inline returns in 43 methods across 30 files, all in src/. getsentry has no extend_schema endpoints. Every one returns a status its schema didn't list, so I documented each with the existing RESPONSE_* constant instead of baselining them: 400, 401, 403, 404, 409 and 429. This adds RESPONSE_GONE for the one 410. Like S021–S023, the rule then runs with no baseline, and tests/* is exempt the same way. These are schema-only additions, with no runtime behavior change. Where a status has a known body shape, a typed response like the ones in #131067 can replace the generic constant later.

The optional prod-vs-dev schema diff check fails by design here: the schema gains those response entries, and nothing is removed.

via @BYK.

--

View Session [Sentry]

Flag a 4xx Response that an @extend_schema(responses=...) method returns
inline when that status isn't a key in responses=. Document the 4xx
statuses the 43 existing violating methods already return, using the
RESPONSE_* constants (adds RESPONSE_GONE for 410). No runtime behavior
change.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 13, 2026
@sentry-junior
sentry-junior Bot marked this pull request as ready for review November 13, 2026 15:37
@sentry-junior
sentry-junior Bot requested review from a team as code owners November 13, 2026 15:37
@sentry-junior
sentry-junior Bot requested a review from BYK November 13, 2026 15:37

@BYK BYK left a comment

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.

Two follow-ups would close the gaps the rule leaves: tightening the mypy plugin so error bodies are checked against their TypedDict (handled separately), and a test-time check of responses against the generated schema (#131073).

Let's do these.

@BYK
BYK enabled auto-merge (squash) November 13, 2026 15:39
…ented-4xx

# Conflicts:
#	tools/flake8_plugin.py
@BYK
BYK merged commit c9f260b into master Nov 13, 2026
70 of 71 checks passed
@BYK
BYK deleted the lint/flake8-undocumented-4xx branch November 13, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant