phalcon/cphalcon · error · Phalcon\Mvc\Url\Exceptions\RouterServiceUnavailable

A dependency injection container is required to access the '

Error message

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

What it means

When Url::get() resolves a named route and no Router was injected directly, the Url component falls back to its DI container (phalcon/Mvc/Url.zep:159). If no container object is attached at all, RouterServiceUnavailable is thrown: named-route URL generation requires either a Router or a container to fetch one from.

Source

Thrown at phalcon/Mvc/Url.zep:159

        if typeof baseUri != "string" {
            let baseUri = this->getBaseUri();
        }

        if typeof uri == "array" {
            if unlikely !fetch routeName, uri["for"] {
                throw new MissingRouteName();
            }

            let router = this->router;

            /**
             * Check if the router has not previously set
             */
            if unlikely !router {
                let container = <DiInterface> this->container;

                if unlikely typeof container != "object" {
                    throw new RouterServiceUnavailable();
                }

                if unlikely !container->has("router") {
                    throw new RouterServiceUnavailable();
                }

                let router       = <RouterInterface> container->getShared("router"),
                    this->router = router;
            }

            /**
             * Every route is uniquely differenced by a name
             */
            let route = <RouteInterface> router->getRouteByName(routeName);

            if unlikely typeof route != "object" {
                throw new RouteNotFound(routeName);
            }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Attach the container: $url->setDI($di) (or setContainer($di)) before generating named-route URLs
  2. Or bypass DI entirely by injecting the router: $url->setRouter($router)
  3. In CLI/test bootstrap, reuse the same DI setup as the web app

Example fix

// before
$url = new \Phalcon\Mvc\Url();
echo $url->get(['for' => 'home']); // no container -> RouterServiceUnavailable

// after
$url = new \Phalcon\Mvc\Url();
$url->setDI($di);
echo $url->get(['for' => 'home']);
Defensive patterns

Strategy: validation

Validate before calling

if ($url->getDI() === null && !$url->getRouter()) {
    throw new \RuntimeException('Attach a DI container or router before named-route URL generation');
}

Try / catch

try {
    $link = $url->get(['for' => 'home']);
} catch (\Phalcon\Mvc\Url\Exceptions\RouterServiceUnavailable $e) {
    $url->setDI($app->getDI()); // lazy-attach then retry
    $link = $url->get(['for' => 'home']);
}

Prevention

When it happens

Trigger: Using $url = new \Phalcon\Mvc\Url() standalone without calling setDI()/setContainer(); using Url inside a CLI worker, queue job, or unit test where the app DI was never attached; copying Url into a service that bypasses the shared container.

Common situations: Unit tests constructing Url manually; long-running workers (cron, queue consumers) that new up components instead of resolving from DI; refactoring code out of a request cycle and losing the container reference.

Related errors


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