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
- Reproduce the exact path from the message and check it: `ls -l <path-from-error>`
- Fix the location: correct the asset's path via `setPath()`/constructor, or adjust the Manager's 'sourceBasePath' option / `$asset->setSourceBasePath()`
- Give the PHP user read permission on the file
- 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
- Assert in CI/build that every registered asset file exists under sourceBasePath
- Configure sourceBasePath from one path constant used by the whole app
- Mark CDN assets setLocal(false) at registration time
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
- Annotations directory cannot be written
- The collection '{name}' does not exist in the manager
- Path '{path}' is not a valid target path
- Path '{path}' is not a valid target path, it is a directory.
- Asset '{path}' does not have a valid source path
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/eb478c992cf3b1b6.
Report an issue: GitHub.