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

Failed to commit router cache: {path}

Error message

Failed to commit router cache: {path}

What it means

After successfully writing the temp file, dumpDispatcher() commits the cache with rename(tmpPath, path). If rename fails it unlinks the temp file and throws 'Failed to commit router cache' with the target path. On POSIX this fails when the target directory lacks write/modify permission, the destination exists as a directory, or the filesystem rejects the operation; on Windows, an existing destination that is open/locked also fails.

Source

Thrown at phalcon/Mvc/Router.zep:937

     * dumps don't corrupt the result.
     *
     * @throws \Phalcon\Mvc\Router\Exception
     */
    public function dumpDispatcher( string path) -> void
    {
        var dump, php, tmpPath;

        let dump    = this->buildDispatcherDump();
        let php     = "<?php\nreturn " . var_export(dump, true) . ";\n";
        let tmpPath = path . ".tmp." . (string) getmypid();

        if this->phpFilePutContents(tmpPath, php) === false {
            throw new Exception("Failed to write router cache temp file: " . tmpPath);
        }

        if !rename(tmpPath, path) {
            this->phpUnlink(tmpPath);
            throw new Exception("Failed to commit router cache: " . path);
        }
    }

    /**
     * File-shaped helper around loadDispatcherFromArray(). Includes the
     * file (opcache-friendly) and forwards the return value.
     *
     * @throws \Phalcon\Mvc\Router\Exception
     */
    public function loadDispatcher( string path) -> void
    {
        var dump;

        if !this->phpFileExists(path) {
            throw new Exception("Router cache not found: " . path);
        }

        let dump = require path;

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Delete the stale cache file and let the current writer recreate it: rm routes.php && re-run dump
  2. Fix ownership/perms so the process calling dumpDispatcher() owns or may replace the target: chown phpuser routes.php / chmod 664 + dir 775
  3. Verify path is a file path, not an existing directory
  4. On Windows/shared mounts, ensure nothing holds the destination open; retry the dump after releasing locks

Example fix

// before
$router->dumpDispatcher($path); // stale read-only file -> rename fails -> throws

// after: remove unreplaceable artifacts before dumping
if (is_file($path) && !is_writable($path)) {
    if (!@unlink($path)) {
        throw new RuntimeException("Cannot replace cache file: {$path}");
    }
}
$router->dumpDispatcher($path);

# shell fix for ownership
# chown www-data:www-data /var/www/app/cache/routes.php
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the dump can actually replace the target before calling dump
if (is_file($path) && !is_writable($path)) {
    if (!@unlink($path)) {
        throw new RuntimeException("Cannot replace router cache file: {$path}");
    }
}
if (is_dir($path)) {
    throw new RuntimeException("Router cache path is a directory: {$path}");
}
$router->dumpDispatcher($path);

Try / catch

try {
    $router->dumpDispatcher($path);
} catch (\Phalcon\Mvc\Router\Exception $e) {
    // rename/commit failed: tmp file is already cleaned up by the router
    $logger->error('Router cache commit failed: ' . $e->getMessage());
    // app continues with runtime-built routes; alert ops to fix perms
}

Prevention

When it happens

Trigger: The target directory is writable enough to create the temp file but the final path is an existing read-only file owned by another user; path points at a directory; another process (editor, antivirus, opcache tool) holds the destination open on Windows; exotic mounts (some network/virtiofs filesystems) that do not support rename-over-existing.

Common situations: Cache file created by root during a manual deploy, then the web user cannot replace it; CI writing caches as one UID and the app runtime as another; stale cache file with 0444 perms; container volumes with unusual rename semantics.

Related errors


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