phalcon/cphalcon · error · Phalcon\Assets\Exceptions\CannotReadAsset

Asset's content for '{path}' cannot be read

Error message

Asset's content for '{path}' cannot be read

What it means

Phalcon\Assets\Asset reads asset files from disk through a private helper that throws CannotReadAsset when the file contents cannot be loaded. The message includes the complete path (source base path + asset path), telling you exactly which file the manager failed to read.

Source

Thrown at phalcon/Assets/Asset.zep:373

     * @return string
     */
    private function checkPath(string property) -> string
    {
        if (true === empty(this->{property})) {
            return this->path;
        }

        return this->{property};
    }

    /**
     * @param string $completePath
     *
     * @throws Exception
     */
    private function throwException(string completePath) -> void
    {
        throw new CannotReadAsset(completePath);
    }
}

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Reproduce the exact path from the message and check it: `ls -l <path-from-error>`
  2. Fix the location: correct the asset's path via `setPath()`/constructor, or adjust the Manager's 'sourceBasePath' option / `$asset->setSourceBasePath()`
  3. Give the PHP user read permission on the file
  4. For remote assets mark them non-local: `$asset->setLocal(false)` so nothing is read from disk

Example fix

// before: manager sourceBasePath does not match the docroot
$assets = new \Phalcon\Assets\Manager(['sourceBasePath' => '/app/']);
// after
$assets = new \Phalcon\Assets\Manager(['sourceBasePath' => '/app/public/']);
Defensive patterns

Strategy: validation

Validate before calling

$source = rtrim($asset->getSourceBasePath(), '/') . '/' . ltrim($asset->getPath(), '/');
if (!is_file($source) || !is_readable($source)) {
    throw new RuntimeException('Asset file missing or unreadable: ' . $source);
}
echo $assets->outputCss();

Try / catch

try {
    echo $assets->outputCss();
} catch (\Phalcon\Assets\Exceptions\CannotReadAsset $e) {
    // fall back to unfiltered <link> tags so the page still renders
    $logger->warning($e->getMessage());
    echo $assets->outputCss(null); // or emit raw tags for each asset path
}

Prevention

When it happens

Trigger: Rendering or filtering an asset whose file is missing or unreadable: `$assets->outputCss()` / `outputJs()` on a collection containing the asset, or `$asset->getContent()`, when `sourceBasePath . path` does not exist or has no read permission; using a remote URL while the asset is still marked local.

Common situations: Wrong 'sourceBasePath' option on Assets\Manager (e.g. pointing at the project root instead of public/); asset path typos; files not deployed or owned by another user; CDN URLs with setLocal(true) left in place.

Related errors


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