phalcon/cphalcon · error · Phalcon\Mvc\Router\Exception

Router cache is missing 'routes' field

Error message

Router cache is missing 'routes' field

What it means

After the version check, loadDispatcherFromArray() requires a 'routes' key holding the array of serialized route definitions. Its absence means the dump is structurally invalid - truncated, hand-written, or produced by something other than buildDispatcherDump(). The loader never guesses defaults; both 'version' and 'routes' must be present and consistent.

Source

Thrown at phalcon/Mvc/Router.zep:835

            convName, converter, rebuiltRoutes, methodRoutesRehydrated,
            candidatesRehydrated, staticRehydrated, innerKey, innerVal,
            scalarIdx, scalarSubKey, mostInnerVal, mostInnerArr;
        int dumpVersion;

        if !isset dump["version"] {
            throw new Exception("Router cache is missing 'version' field");
        }

        let dumpVersion = (int) dump["version"];

        if dumpVersion !== 1 {
            throw new Exception(
                "Router cache version " . dumpVersion . " is not supported (this build supports version 1)"
            );
        }

        if !isset dump["routes"] {
            throw new Exception("Router cache is missing 'routes' field");
        }

        let rebuiltRoutes = [];

        for routeData in dump["routes"] {
            let routeClass = routeData["class"];
            let route      = new {routeClass}(routeData["pattern"], routeData["paths"], routeData["methods"]);

            if routeData["hostname"] !== null {
                route->setHostname(routeData["hostname"]);
            }

            if routeData["name"] !== null {
                route->setName(routeData["name"]);
            }

            route->setRouteId(routeData["id"]);

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Regenerate the dump with dumpDispatcher()/buildDispatcherDump() so 'routes' is populated by the dumper itself
  2. Clear the offending cache file/key and let the cold path rebuild it
  3. Pre-validate structure before loading: isset($dump['version'], $dump['routes']) and is_array($dump['routes'])
  4. Give the router cache a dedicated, unique key/path so unrelated data cannot collide with it

Example fix

// before
$router->loadDispatcher($path); // dump missing 'routes' -> throws

// after: validate then rebuild on any structural miss
$dump = is_file($path) ? require $path : null;
if (!is_array($dump) || !isset($dump['version'], $dump['routes'])) {
    buildRoutes($router)->dumpDispatcher($path); // regenerate
    $dump = require $path;
}
$router->loadDispatcherFromArray($dump);
Defensive patterns

Strategy: validation

Validate before calling

$dump = is_file($path) ? require $path : null;
if (!is_array($dump) || !isset($dump['routes']) || !is_array($dump['routes'])) {
    buildRoutes($router)->dumpDispatcher($path); // regenerate valid structure
    $dump = require $path;
}
$router->loadDispatcherFromArray($dump);

Type guard

function isRouterDumpShape(mixed $dump): bool
{
    return is_array($dump)
        && isset($dump['version'], $dump['routes'])
        && is_array($dump['routes']);
}

Try / catch

try {
    $router->loadDispatcher($path);
} catch (\Phalcon\Mvc\Router\Exception $e) {
    @unlink($path);
    buildRoutes($router)->dumpDispatcher($path);
    $router->loadDispatcher($path);
}

Prevention

When it happens

Trigger: Passing an array that has 'version' => 1 but no 'routes' (hand-crafted or partially built); a cache file whose var_export output was cut off after the header; a cache entry that was overwritten by another structure that happens to contain a 'version' key.

Common situations: Hand-rolled 'optimized' route caches that mimic the format but omit fields; corrupt cache files from interrupted writes; cache-store key collisions with application data that also uses a 'version' field; test fixtures with minimal arrays passed straight to the loader.

Related errors


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