phalcon/cphalcon · error · Phalcon\Mvc\Router\Exceptions\RequestServiceUnavailable
A dependency injection container is required to access the '
Error message
A dependency injection container is required to access the 'request' service
What it means
Router::handle() resolves the incoming URI from the 'request' service, which it fetches from the router's DI container. If no container was ever assigned (setDI never called and the router was not resolved through DI), the container is null and handle() aborts with RequestServiceUnavailable before any route matching starts.
Source
Thrown at phalcon/Mvc/Router.zep:1265
let currentHostName = null,
routeFound = false,
parts = [],
params = [],
matches = null,
this->wasMatched = false,
this->matchedRoute = null;
let eventsManager = this->eventsManager;
if eventsManager !== null {
eventsManager->fire("router:beforeCheckRoutes", this);
}
/**
* Retrieve the request service from the container
*/
let container = <DiInterface> this->container;
if container === null {
throw new RequestServiceUnavailable();
}
let request = <RequestInterface> container->get("request");
/**
* Build a candidate list of routes that match the request method.
* Routes with no HTTP constraint are stored under "*" and are always
* included. This avoids iterating the full route array per request.
*/
if this->methodRoutesDirty {
this->rebuildMethodIndex();
}
let requestMethod = request->getMethod(),
candidateRoutes = [];
if !fetch candidateRoutes, this->candidatesByMethod[requestMethod] {
fetch candidateRoutes, this->candidatesByMethod["*"];View on GitHub (pinned to b7419de9cd)
Solutions
- Inject the container before handling: $router->setDI($di) with a registered 'request' service (Phalcon\Http\Request or a double)
- Register the router as a DI service ('router' with definition or closure receiving $di) so it is constructed wired-up
- For tests, provide a minimal container: $di->set('request', fn() => $requestStub)
- Ensure 'request' is registered under exactly that service name before calling handle()
Example fix
// before
$router = new \Phalcon\Mvc\Router();
$router->handle(); // no container -> throws RequestServiceUnavailable
// after
$di = new \Phalcon\Di\Di();
$di->set('request', fn() => new \Phalcon\Http\Request());
$router = new \Phalcon\Mvc\Router(false); // no default routes needed
$router->setDI($di);
$router->handle(); // 'request' resolvable Defensive patterns
Strategy: validation
Validate before calling
// Ensure the router can resolve 'request' before handling
$di = $router->getDI();
if ($di === null || !$di->has('request')) {
throw new RuntimeException('Router needs a DI container with a "request" service before handle()');
}
$router->handle(); Type guard
function routerIsWired(\Phalcon\Mvc\Router $router): bool
{
$di = $router->getDI();
return $di instanceof \Phalcon\Di\DiInterface && $di->has('request');
} Try / catch
try {
$router->handle();
} catch (\Phalcon\Mvc\Router\Exceptions\RequestServiceUnavailable $e) {
$router->setDI(bootstrapDi()); // wire a container with 'request', then retry once
$router->handle();
} Prevention
- Construct the router through DI (register 'router' as a service) so it is always container-wired
- In tests, provide a minimal Di with a request double before calling handle()
- Add a bootstrap assertion that getDI() is non-null for any router used standalone
When it happens
Trigger: Standalone usage: $router = new Router(); $router->handle(); without setDI(); unit tests exercising route matching directly; using the Mvc Router in a CLI worker or micro context where no 'request' service was registered; constructing the router manually in a service provider but forgetting to inject the container.
Common situations: Testing routers in isolation (a minimal DI with a request double is needed); moving routing bootstrap out of the main DI setup; Micro apps mixing their own request handling with the full Router; forgetting that handle() reads the URI from the service even when a URI was set explicitly.
Related errors
- Arguments must be an array or string, {type} given
- Before-Match callback is not callable in matched route '{pat
- Before-Match callback is not callable in matched route '{pat
- The route contains invalid paths ('{pattern}')
- Argument at position {} must have a type
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/3fd6b771758f733b.
Report an issue: GitHub.