Skip to content

fix(validator): strict query param validation rejecting pagination params - #8544

Open
jannes-io wants to merge 1 commit into
api-platform:4.4from
jannes-io:fix/strict-query-parameter-validation-pagination
Open

jannes-io wants to merge 1 commit into
api-platform:4.4from
jannes-io:fix/strict-query-parameter-validation-pagination

Conversation

@jannes-io

@jannes-io jannes-io commented Sep 18, 2026

Copy link
Copy Markdown
Contributor
Q A
Branch? 4.4
Tickets Closes #8543
License MIT
Doc PR

Warning

This PR was partially generated using AI. The resulting code was checked by myself for potential issues.

When strictQueryParameterValidation is enabled on a GetCollection operation, pagination query parameters (page, itemsPerPage, pagination, partial) were always rejected with Parameter "X" not supported, even with no other configuration involved. There were actually two separate, compounding bugs:

  1. Pagination parameters are never registered in the Parameter/Parameters system. ParameterProvider::provide() builds its whitelist from $operation->getParameters(), but pagination values are read directly from the request/context in State\Pagination\Pagination — completely bypassing that whitelist. The only place these names existed as Parameter-like objects was OpenApiFactory::getPaginationParameters(), which is purely for Swagger docs. So the docs showed them, but validation rejected them.
  2. api_platform.defaults.parameters (global default parameters) silently disabled an existing fallback. ParameterValidationResourceMetadataCollectionFactory::addFilterValidation() auto-whitelists filter-derived query keys, but only when 0 === $parameters->count(). Since global default parameters are merged into every operation's Parameters before that check runs, declaring even one global default parameter (e.g. a custom HeaderParameter) bumped every operation's count above zero and silently skipped this fallback everywhere — unrelated filter-based query keys started getting rejected too.

Changes

  • src/State/Provider/ParameterProvider.php: inject the existing PaginationOptions service and whitelist page/itemsPerPage/pagination/partial for CollectionOperationInterface operations during strict validation, mirroring the exact conditions OpenApiFactory::getPaginationParameters() already uses (so docs and validation agree, including with renamed pagination parameters via the global config). Also fixed a latent null-safety warning on the same line (foreach over getParameters() when it's null, which is the common case for a collection operation with no filters).
  • src/Validator/Metadata/Resource/Factory/ParameterValidationResourceMetadataCollectionFactory.php: the 0 === $parameters->count() guard now excludes parameters injected purely from global defaults.parameters, so declaring a global default parameter no longer disables filter-based whitelisting for every other operation.
  • src/Symfony/Bundle/Resources/config/state/provider.php: wire api_platform.pagination_options into the ParameterProvider service.
  • src/Laravel/ApiPlatformDeferredProvider.php: same wiring for Laravel's ParameterProvider registration (already had PaginationOptions bound).

Tests

  • src/State/Tests/ParameterProviderTest.php: unit tests covering pagination whitelisting, unknown-parameter rejection, item-operation scoping (pagination params aren't whitelisted on non-collection operations), renamed pagination parameters (e.g. itemsPerPage_limit via global config), and BC when PaginationOptions isn't injected.
  • src/Validator/Tests/Metadata/Resource/Factory/ParameterValidationResourceMetadataCollectionFactoryTest.php (new): reproduces the defaults.parameters-defeats-filter-whitelisting bug directly against the factory.
  • tests/Functional/Parameters/StrictParametersCollectionTest.php + new fixture tests/Fixtures/TestBundle/ApiResource/StrictParametersCollection.php: full HTTP-level reproduction of the exact Parameter "page" not supported error from the issue report, and confirmation that unknown parameters are still correctly rejected.

All new tests fail against the code prior to this PR and pass after. Existing test suites (src/State, src/Validator, tests/Functional/Parameters/StrictParametersTest, tests/Functional/DefaultParametersTest) pass unmodified, confirming no regression to OpenAPI doc generation or existing strict-validation behavior.

@jannes-io
jannes-io force-pushed the fix/strict-query-parameter-validation-pagination branch 3 times, most recently from 717ef41 to 7d8eb49 Compare September 18, 2026 09:04

@soyuka soyuka 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.

target 4.4 please

Comment thread src/State/Provider/ParameterProvider.php Outdated
@jannes-io jannes-io changed the title fix strict query param validation rejecting pagination params fix(validator): strict query param validation rejecting pagination params Sep 18, 2026
@jannes-io
jannes-io force-pushed the fix/strict-query-parameter-validation-pagination branch 2 times, most recently from 2be1393 to 4b18b36 Compare September 18, 2026 09:27
@jannes-io
jannes-io changed the base branch from 4.3 to 4.4 September 18, 2026 09:27
@jannes-io
jannes-io force-pushed the fix/strict-query-parameter-validation-pagination branch 2 times, most recently from 4cce8d2 to 7bdefa3 Compare September 18, 2026 10:08
@jannes-io

Copy link
Copy Markdown
Contributor Author

Ok, just waiting for CI to be completed.

The Mercure failure seems unrelated and happens on other PRs as well.

@jannes-io
jannes-io requested a review from soyuka September 18, 2026 10:19
@jannes-io
jannes-io force-pushed the fix/strict-query-parameter-validation-pagination branch from 7bdefa3 to fd970f3 Compare September 18, 2026 10:22
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