phalcon/cphalcon · error · Phalcon\Filter\Validation\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
Validation::bind() pre-sanitizes incoming data through the DI 'filter' service, so it needs a service container. FilterServiceUnavailable is thrown when the validation object has no container injected (getDI() is null) and the global default container Di::getDefault() is also null — i.e., the validation runs standalone with no DI anywhere.
Source
Thrown at phalcon/Filter/Validation.zep:203
*/
public function bind(var entity, var data, array whitelist = []) -> <static>
{
var container, field, value, fieldFilters, filterService, filters, method;
let this->data = data;
this->setEntity(entity);
// if data is not an array / object, entity is null, or data is empty, then no need to proceed further
if unlikely (typeof data != "array" && typeof data != "object") || (null === entity) || empty data {
return this;
}
let container = this->getDI();
if container === null {
let container = Di::getDefault();
if container === null {
throw new FilterServiceUnavailable();
}
}
let filterService = <FilterInterface> container->getShared("filter");
if unlikely typeof filterService != "object" {
throw new InvalidFilterService();
}
if empty whitelist {
let whitelist = this->whitelist;
}
let filters = this->filters;
for field, value in data {
/**
* Skip numeric (integer) keys; entity setters and properties are
* always string-named, so camelize() would fail on them. See
* cphalcon issue #17173.View on GitHub (pinned to b7419de9cd)
Solutions
- Set a container on the validation: $validation->setDI(new FactoryDefault()) (or your existing $di)
- Or establish the global default once at bootstrap: Di::setDefault($di)
- Ensure the container actually defines a 'filter' service once the container issue is fixed (next error will be FilterServiceUnavailable/InvalidFilterService otherwise)
Example fix
// before $v = new Validation(); $v->bind($entity, $_POST); // throws FilterServiceUnavailable: no DI anywhere // after $di = new FactoryDefault(); Di::setDefault($di); $v = new Validation(); $v->setDI($di); $v->bind($entity, $_POST);
Defensive patterns
Strategy: validation
Validate before calling
if ($validation->getDI() === null && Di::getDefault() === null) {
throw new RuntimeException('Validation needs a DI container with a filter service; call setDI() or Di::setDefault()');
}
$validation->bind($entity, $data); Type guard
function hasFilterContainer(\Phalcon\Filter\Validation $v): bool
{
return $v->getDI() !== null || \Phalcon\Di\Di::getDefault() !== null;
} Try / catch
use Phalcon\Filter\Validation\Exceptions\FilterServiceUnavailable;
try {
$v->bind($entity, $data);
} catch (FilterServiceUnavailable $e) {
$v->setDI(new FactoryDefault()); // bootstrap on demand in workers/CLI
$v->bind($entity, $data);
} Prevention
- Call Di::setDefault($di) once at process start — CLI scripts, queue workers and tests included
- Inject the container into every standalone Validation: setDI($di)
- In long-running workers, re-establish the container after any Di::reset()
When it happens
Trigger: $v = new Validation(); $v->bind($entity, $data); in a plain PHP script, unit test, or queue worker where no FactoryDefault was ever created; calling bind() before Di::setDefault() runs; Di::reset() in a test tearDown leaving the default container null while a later bind() still executes.
Common situations: Using Phalcon\Filter\Validation outside a full Phalcon application (micro-service, CLI script, PHPUnit); long-running workers started before the DI was bootstrapped; tests that reset DI state between cases.
Related errors
- Argument at position {} must have a type
- Service '{}' is required in parameter on position {}
- Service 'value' is required in parameter on position {}
- Service 'className' is required in parameter on position {}
- Unknown service type in parameter on position {}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/ac2a6e350c0ba244.
Report an issue: GitHub.