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

Route config entry is missing 'paths'

Error message

Route config entry is missing 'paths'

What it means

Companion to the 'pattern' check: every entry in config['routes'] must also contain a 'paths' key (the controller/action/parameter map applied when the pattern matches). MissingRouteConfigKey('paths') is thrown when routeData['paths'] cannot be fetched.

Source

Thrown at phalcon/Mvc/Router.zep:2065

    }

    /**
     * Adds a single route from a config array entry. Used by loadFromConfig.
     *
     * @param array routeData
     *
     * @return void
     */
    protected function addRouteFromConfig(array routeData) -> void
    {
        var method, methodClass, pattern, paths, route;

        if !fetch pattern, routeData["pattern"] {
            throw new MissingRouteConfigKey("pattern");
        }

        if !fetch paths, routeData["paths"] {
            throw new MissingRouteConfigKey("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":
            case "post":
            case "purge":
            case "put":

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Add an explicit paths map, even if minimal: {"pattern": "/about", "paths": {"controller": "about", "action": "index"}}
  2. Use exactly the key 'paths' (lowercase, plural)
  3. Pre-validate entries for both required keys (see validation snippet)

Example fix

// before
{
    "routes": [
        {"pattern": "/about"}
    ]
}

// after
{
    "routes": [
        {
            "pattern": "/about",
            "paths": {"controller": "about", "action": "index"}
        }
    ]
}
Defensive patterns

Strategy: validation

Validate before calling

foreach ($config['routes'] ?? [] as $i => $entry) {
    if (!is_array($entry) || !isset($entry['pattern'], $entry['paths'])) {
        throw new InvalidArgumentException(
            "routes[$i] must define both 'pattern' and 'paths'"
        );
    }
}

$router->loadFromConfig($config);

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: {"pattern": "/about"} with no "paths"; key written as "path", "defaults", or "target"; an intentionally empty destinations object written as a string or omitted entirely.

Common situations: Assuming a pattern-only route defaults somewhere; refactoring that dropped the paths element; differing conventions between projects (paths vs defaults naming).

Related errors


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