{"record":{"id":"847f8361a4e79def","repo":"slimphp/Slim","slug":"route-not-found-looks-like-your-route-cache-is-st","errorCode":null,"errorMessage":"Route not found, looks like your route cache is stale.","messagePattern":"Route not found, looks like your route cache is stale\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"Slim/Routing/RouteCollector.php","lineNumber":222,"sourceCode":"        }\n\n        foreach ($this->routes as $route) {\n            if ($name === $route->getName()) {\n                $this->routesByName[$name] = $route;\n                return $route;\n            }\n        }\n\n        throw new RuntimeException('Named route does not exist for name: ' . $name);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function lookupRoute(string $identifier): RouteInterface\n    {\n        if (!isset($this->routes[$identifier])) {\n            throw new RuntimeException('Route not found, looks like your route cache is stale.');\n        }\n        return $this->routes[$identifier];\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function group(string $pattern, $callable): RouteGroupInterface\n    {\n        $routeGroup = $this->createGroup($pattern, $callable);\n        $this->routeGroups[] = $routeGroup;\n\n        $routeGroup->collectRoutes();\n        array_pop($this->routeGroups);\n\n        return $routeGroup;\n    }\n","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/slimphp/Slim/blob/80900fb39cafce3ae53b18a2c4f642a122f03095/Slim/Routing/RouteCollector.php#L204-L240","documentation":"During dispatch, RoutingMiddleware resolves the matched route identifier via RouteResolver->lookupRoute(), which searches only the in-memory $routes array of the live RouteCollector. When FastRoute reports FOUND but the identifier is missing in memory, it almost always means the dispatcher was built from a cached route set that no longer matches the routes actually registered in this process — hence the 'route cache is stale' message. It is a cache/definition desynchronization error, not a '404 the URL is wrong' error.","triggerScenarios":"Enabling setCacheFile() and then changing, adding, or removing route definitions without deleting the cache file; registering routes conditionally (per environment, per debug flag, per tenant) so the cache was generated with a different set than the running process has; reusing a cache file committed to VCS or baked into a build artifact across code releases; two applications sharing one cache file.","commonSituations":"Deploy new code with an old routes.php cache left in cache/ from the previous build; a CI-built Docker image that copies a stale cache; routes defined inside if (env('DEBUG')) blocks so dev and prod need different caches; every request then throws this RuntimeException instead of serving the route, so the app appears hard-down after deploy.","solutions":["Delete the route cache file (e.g. rm var/cache/routes.php) so it is regenerated from the current definitions, then reload","Add cache invalidation to the deploy pipeline: clear the route cache whenever any route definition file changes","Make route registration deterministic — never register routes conditionally on environment/debug flags while caching is enabled","Give each app and each environment its own cache file; never commit or share route caches across releases"],"exampleFix":"// before\n$cacheFile = __DIR__ . '/var/cache/routes.php';\n$app->getRouteCollector()->setCacheFile($cacheFile); // cache from an older deploy, identifiers no longer match\n\n// after — invalidate in bootstrap/deploy when definitions change\n$cacheFile = __DIR__ . '/var/cache/routes.php';\nif (file_exists($cacheFile) && filemtime($cacheFile) < filemtime(__DIR__ . '/config/routes.php')) {\n    unlink($cacheFile); // force regeneration from current definitions\n}\n$app->getRouteCollector()->setCacheFile($cacheFile);","handlingStrategy":"fallback","validationCode":"// bootstrap guard: drop the cache whenever any route definition source is newer\n$cacheFile = __DIR__ . '/var/cache/routes.php';\n$sources = glob(__DIR__ . '/config/routes/*.php');\nif (file_exists($cacheFile)) {\n    $cacheAge = filemtime($cacheFile);\n    foreach ($sources as $src) {\n        if (filemtime($src) > $cacheAge) {\n            unlink($cacheFile);\n            break;\n        }\n    }\n}\n$app->getRouteCollector()->setCacheFile($cacheFile);","typeGuard":null,"tryCatchPattern":"try {\n    $response = $app->handle($request);\n} catch (RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'route cache is stale')) {\n        // one-shot recovery: drop the cache, force regeneration, retry once\n        @unlink($cacheFile);\n        $response = $app->handle($request);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Treat the route cache as a build artifact: clear it in the same deploy step that ships route changes","Never register routes conditionally (env/debug/tenant) when caching is enabled — one cache must fit all requests","Give each app and environment a unique cache file path; exclude it from VCS and shared images","Add a post-deploy health request (curl /) that would surface a stale cache before real users hit it"],"tags":["slim","php","routing","cache","deployment","stale-cache"],"backgroundTag":"stale-route-cache","analyzedSha":"80900fb39cafce3ae53b18a2c4f642a122f03095","analyzedAt":"2026-08-21T01:41:09.580Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}