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

A dependency injection container is required to access the '

Error message

A dependency injection container is required to access the 'filter' service

What it means

Request::getFilterService() lazily resolves the 'filter' service: if no FilterInterface was injected (setFilterService()) it falls back to container->getShared('filter'). It throws FilterServiceUnavailable when the Request has no container at all - typical for Request objects created standalone outside a bootstrapped application.

Source

Thrown at phalcon/Http/Request.zep:1888

        }

        return files;
    }

    /**
     * Checks the filter service and assigns it to the class parameter
     */
    private function getFilterService() -> <FilterInterface>
    {
        var container, filterService;

        let filterService = this->filterService;

        if typeof filterService != "object" {
            let container = <DiInterface> this->container;

            if container === null {
                throw new FilterServiceUnavailable();
            }

            let filterService       = <FilterInterface> container->getShared("filter"),
                this->filterService = filterService;
        }

        return this->filterService;
    }

    /**
     * Parses multipart/form-data from the raw body.
     *
     * @phpstan-return http_form_data
     */
    private function getFormData() -> array
    {
        var boundary, matches;

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Attach a container: $request->setDI($di) - FactoryDefault already defines 'filter'
  2. Or inject the filter directly: $request->setFilterService($filter);
  3. Use Phalcon\Http\RequestFactory::newInstance() which wires dependencies correctly
  4. In CLI/tests, set a default container once: Di::setDefault(new FactoryDefault());

Example fix

// before
$request = new \Phalcon\Http\Request();
$email = $request->getFilteredPost('email'); // throws: no container

// after
$di = new \Phalcon\Di\FactoryDefault();
$request = new \Phalcon\Http\Request();
$request->setDI($di);
$email = $request->getFilteredPost('email');
Defensive patterns

Strategy: validation

Validate before calling

// standalone Request usage: attach a container before any getFiltered* call
use Phalcon\Di\Di;

if (null === Di::getDefault()) {
    Di::setDefault(new \Phalcon\Di\FactoryDefault());
}
$request->setDI(Di::getDefault());
$email = $request->getFilteredPost('email');

Try / catch

try { $value = $request->getFilteredPost('email'); } catch (\Phalcon\Http\Request\Exceptions\FilterServiceUnavailable $e) { // wiring bug: fix DI, do not swallow
    $request->setDI(new \Phalcon\Di\FactoryDefault());
    $value = $request->getFilteredPost('email');
}

Prevention

When it happens

Trigger: $request = new Request(); $request->getFilteredPost('email'); (or any setParameterFilters/getFiltered* path) where setDI() was never called and Di::getDefault() is null - CLI workers, unit tests, micro-apps.

Common situations: Unit tests constructing Request directly; long-running CLI workers parsing request payloads; code that clones or rebuilds Request before a container is attached.

Related errors


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