phalcon/cphalcon · error · Phalcon\Mvc\Router\Exceptions\MissingGroupRouteKey

Group route entry is missing 'pattern'

Error message

Group route entry is missing 'pattern'

What it means

Inside every group route definition (config['groups'][*]['routes'][*]), the 'pattern' key is mandatory. When mountGroupFromConfig iterates a group's routes and cannot fetch routeData['pattern'], it throws MissingGroupRouteKey('pattern') naming the key.

Source

Thrown at phalcon/Mvc/Router.zep:2146

        if isset groupData["prefix"] {
            group->setPrefix((string) groupData["prefix"]);
        }

        if isset groupData["hostname"] {
            group->setHostname((string) groupData["hostname"]);
        }

        if !fetch routes, groupData["routes"] {
            let routes = [];
        }

        if typeof routes !== "array" {
            throw new GroupRoutesMustBeArray();
        }

        for routeData in routes {
            if !fetch pattern, routeData["pattern"] {
                throw new MissingGroupRouteKey("pattern");
            }
            if !fetch routePaths, routeData["paths"] {
                throw new MissingGroupRouteKey("paths");
            }

            let method = "";
            if isset routeData["method"] && routeData["method"] !== null {
                let method = strtolower((string) routeData["method"]);
            }

            switch method {
                case "":
                case "connect":
                case "delete":
                case "get":
                case "head":
                case "options":
                case "patch":

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Add "pattern" to every group route entry: {"pattern": "/dashboard", "paths": {...}}
  2. Use exactly the key 'pattern'
  3. Validate nested group routes up front (see validation snippet) to catch the entry index

Example fix

// before
"groups": [
    {
        "prefix": "/admin",
        "routes": [
            {"paths": {"controller": "dashboard", "action": "index"}}
        ]
    }
]

// after
"groups": [
    {
        "prefix": "/admin",
        "routes": [
            {
                "pattern": "/dashboard",
                "paths": {"controller": "dashboard", "action": "index"}
            }
        ]
    }
]
Defensive patterns

Strategy: validation

Validate before calling

// walk groups and verify each nested route entry has pattern + paths
foreach ($config['groups'] ?? [] as $g => $group) {
    foreach ($group['routes'] ?? [] as $i => $entry) {
        if (!is_array($entry) || !isset($entry['pattern'], $entry['paths'])) {
            throw new InvalidArgumentException(
                "groups[$g].routes[$i] must define both 'pattern' and 'paths'"
            );
        }
    }
}

$router->loadFromConfig($config);

Type guard

function groupRouteEntryIsValid(mixed $entry): bool
{
    return is_array($entry) && isset($entry['pattern'], $entry['paths']);
}

Try / catch

try {
    $router->loadFromConfig($config);
} catch (\Phalcon\Mvc\Router\Exceptions\MissingGroupRouteKey $e) {
    $logger->error('Group route entry rejected: ' . $e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: A group route entry {"paths": {...}} without "pattern"; key spelled "match" or "path"; pattern left out while converting inline group->add() calls to config.

Common situations: Porting programmatic groups into config files and dropping the first constructor argument's equivalent; inconsistent generators; partial copy-paste between route entries.

Related errors


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