symfony/translation · error · NotFoundResourceException
Error opening file " ".
Error message
Error opening file "%s".
What it means
CsvFileLoader::loadResource() opens the CSV translation file with fopen(); when fopen() fails (returns false, error suppressed with @) it throws NotFoundResourceException. This means the resource path/stream passed to load() could not be opened for reading.
Solutions
- Verify the resource path exists with file_exists($resource) before loading and fix the path.
- Check file read permissions for the PHP process user (e.g. chmod/chown on the translations directory).
- Ensure the file is actually a readable regular file, not a directory or broken symlink.
- Catch NotFoundResourceException in your loader/translation-container setup and fail gracefully or fall back to an empty catalogue.
Example fix
// before
$loader->load('trans/messages.csv', 'en');
// after
$path = __DIR__.'/translations/messages.en.csv';
if (!is_file($path) || !is_readable($path)) {
throw new \RuntimeException("CSV translation file missing or unreadable: $path");
}
$loader->load($path, 'en'); Defensive patterns
Strategy: validation
Validate before calling
$path = $resource;
if (!is_string($path) || !is_file($path) || !is_readable($path)) {
throw new \InvalidArgumentException("Unreadable CSV translation file: $path");
} Type guard
function isReadableFile(mixed $r): bool { return is_string($r) && is_file($r) && is_readable($r); } Try / catch
try {
$catalogue = $loader->load($path, 'en');
} catch (Symfony\Component\Translation\Exception\NotFoundResourceException $e) {
$catalogue = new MessageCatalogue('en'); // fallback
} Prevention
- Always check is_file() and is_readable() before calling load().
- Build paths with %kernel.project_dir% or __DIR__ instead of relative paths.
- Add translation files to deployment artifacts and verify in CI.
- Log the exact path in the exception context for debugging.
When it happens
Trigger: Calling CsvFileLoader::load($resource, $locale, $domain) with a path that does not exist, has wrong read permissions, is a directory, or an unreadable stream (fopen returns false).
Common situations: Typo in the translation file path, missing '%kernel.project_dir%/translations' prefix, file not deployed to the server, wrong permissions after container build, or passing a URL/stream wrapper fopen cannot open.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- File " " not found.
- The " " file does not exist.
- This is not a local file
- Unable to load file " ".
- File " " not found.
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/2a73dd5909494a60.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/CsvFileLoader.php:31
use Symfony\Component\Translation\Exception\NotFoundResourceException;
/**
* CsvFileLoader loads translations from CSV files.
*
* @author Saša Stamenković <umpirsky@gmail.com>
*/
class CsvFileLoader extends FileLoader
{
private string $delimiter = ';';
private string $enclosure = '"';
protected function loadResource(string $resource): array
{
$messages = [];
if (!$file = @fopen($resource, 'r')) {
throw new NotFoundResourceException(\sprintf('Error opening file "%s".', $resource));
}
try {
while (false !== $data = fgetcsv($file, null, $this->delimiter, $this->enclosure, '')) {
// empty lines are read as [null]
if (isset($data[1]) && 2 === \count($data) && !str_starts_with($data[0], '#')) {
$messages[$data[0]] = $data[1];
}
}
} finally {
fclose($file);
}
return $messages;
}
/**
* Sets the delimiter and enclosure character for CSV.View on GitHub (pinned to ae9e8a51bc)