phalcon/cphalcon · error · Phalcon\Http\Request\Exceptions\SanitizerNotFound

Sanitizer '{sanitizer}' does not exist in the filter locator

Error message

Sanitizer '{sanitizer}' does not exist in the filter locator

What it means

Every name passed to Request::setParameterFilters() is checked against the Filter service locator with has($sanitizer); an unknown name throws SanitizerNotFound. Out of the box the locator knows Phalcon's built-in sanitizers ('string', 'int', 'float', 'email', 'trim', 'lower', 'upper', 'striptags', ...); custom names must be registered on the Filter service via set() before use.

Source

Thrown at phalcon/Http/Request.zep:1450

     * @phpstan-param list<string> $filters
     * @phpstan-param list<string> $scope
     */
    public function setParameterFilters(
         string name,
        array filters = [],
        array scope = []
    ) -> <static> {
        var filterService, sanitizer, localScope, scopeMethod;

        if unlikely empty filters {
            throw new MissingFilters(name);
        }

        let filterService = this->getFilterService();

        for sanitizer in filters {
            if unlikely true !== filterService->has(sanitizer) {
                throw new SanitizerNotFound(sanitizer);
            }
        }

        if empty scope {
            let localScope = [
                self::METHOD_GET,
                self::METHOD_PATCH,
                self::METHOD_POST,
                self::METHOD_PUT
            ];
        } else {
            let localScope = scope;
        }

        for scopeMethod in localScope {
            let this->queryFilters[strtoupper(scopeMethod)][name] = filters;
        }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Use built-in names exactly: 'string', 'int', 'float', 'email', 'trim', 'lower', 'upper', 'striptags', 'special'
  2. Register custom sanitizers on the filter service first: $filter = $di->getShared('filter'); $filter->set('slug', MySlugFilter::class);
  3. Validate names before calling: assert($filter->has($sanitizer)) for each entry

Example fix

// before
$request->setParameterFilters('slug', ['slug']); // SanitizerNotFound if unregistered

// after
$filter = $di->getShared('filter');
if (!$filter->has('slug')) {
    $filter->set('slug', \App\Filter\SlugFilter::class);
}
$request->setParameterFilters('slug', ['slug']);
Defensive patterns

Strategy: validation

Validate before calling

$filter = $di->getShared('filter');
foreach ($filters as $sanitizer) {
    if (!$filter->has($sanitizer)) {
        throw new \InvalidArgumentException(sprintf('Unknown sanitizer "%s"', $sanitizer));
    }
}
$request->setParameterFilters($name, $filters);

Try / catch

try { $request->setParameterFilters($name, $filters); } catch (\Phalcon\Http\Request\Exceptions\SanitizerNotFound $e) { // surface the bad name, fix config before deploy
    error_log($e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: setParameterFilters('name', ['intiger']) (typo), ['escape_string'] (never built-in), or a custom sanitizer defined in DI but never added to the filter locator.

Common situations: Typos in sanitizer names; assuming framework-ish names like 'escape' or 'xss' exist; defining custom sanitizers in the container but forgetting to attach them to the Filter service.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/04bd6443a261d62b. Report an issue: GitHub.