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

It's necessary to define the route name with the parameter '

Error message

It's necessary to define the route name with the parameter 'for'

What it means

Phalcon\Mvc\Url::get() has a dual API: a string URI is returned prefixed with baseUri, but an array is interpreted as a named-route lookup that MUST contain a 'for' key naming the route (see phalcon/Mvc/Url.zep:147). If the fetch of uri['for'] fails, MissingRouteName is thrown because there is no route name to resolve against the router.

Source

Thrown at phalcon/Mvc/Url.zep:147

        if local == null {
            if typeof uri == "string" && (memstr(uri, "//") || memstr(uri, ":")) {
                if preg_match("#^((//)|([a-z0-9]+://)|([a-z0-9]+:))#i", uri) {
                    let local = false;
                } else {
                    let local = true;
                }
            } else {
                let local = true;
            }
        }

        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();
                }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Add 'for' => '<route-name>' as the first entry of the array, keeping other entries as pattern placeholders
  2. For plain paths with query params, pass a string URI and use the second argument: $url->get('products/search', ['page' => 2])
  3. Verify with isset($uri['for']) before calling when the array is built dynamically

Example fix

// before
$link = $url->get(['controller' => 'posts', 'action' => 'show', 'id' => 7]);

// after
$link = $url->get(['for' => 'post-show', 'id' => 7]); // named route with {id} placeholder
Defensive patterns

Strategy: validation

Validate before calling

if (is_array($uri) && !isset($uri['for'])) {
    throw new \InvalidArgumentException("Url::get() array URI requires a 'for' key naming the route");
}

Type guard

function isNamedRouteUri(mixed $uri): bool
{
    return !is_array($uri) || array_key_exists('for', $uri);
}

Prevention

When it happens

Trigger: $url->get(['param' => 1, 'id' => 5]) intending query-string params but omitting 'for'; using 'name' or 'route' as the key instead of 'for'; building the array dynamically so the 'for' entry is conditionally dropped.

Common situations: Assuming Url::get(array) appends a query string (it does not — query args go as the second parameter); typos in the magic 'for' key; array_merge/array_filter accidentally removing the key.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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