{"record":{"id":"2a73dd5909494a60","repo":"symfony/translation","slug":"error-opening-file-s","errorCode":null,"errorMessage":"Error opening file \"%s\".","messagePattern":"Error opening file \"(.+?)\"\\.","errorType":"exception","errorClass":"NotFoundResourceException","httpStatus":null,"severity":"error","filePath":"Loader/CsvFileLoader.php","lineNumber":31,"sourceCode":"\nuse Symfony\\Component\\Translation\\Exception\\NotFoundResourceException;\n\n/**\n * CsvFileLoader loads translations from CSV files.\n *\n * @author Saša Stamenković <umpirsky@gmail.com>\n */\nclass CsvFileLoader extends FileLoader\n{\n    private string $delimiter = ';';\n    private string $enclosure = '\"';\n\n    protected function loadResource(string $resource): array\n    {\n        $messages = [];\n\n        if (!$file = @fopen($resource, 'r')) {\n            throw new NotFoundResourceException(\\sprintf('Error opening file \"%s\".', $resource));\n        }\n\n        try {\n            while (false !== $data = fgetcsv($file, null, $this->delimiter, $this->enclosure, '')) {\n                // empty lines are read as [null]\n                if (isset($data[1]) && 2 === \\count($data) && !str_starts_with($data[0], '#')) {\n                    $messages[$data[0]] = $data[1];\n                }\n            }\n        } finally {\n            fclose($file);\n        }\n\n        return $messages;\n    }\n\n    /**\n     * Sets the delimiter and enclosure character for CSV.","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Loader/CsvFileLoader.php#L13-L49","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\n$loader->load('trans/messages.csv', 'en');\n// after\n$path = __DIR__.'/translations/messages.en.csv';\nif (!is_file($path) || !is_readable($path)) {\n    throw new \\RuntimeException(\"CSV translation file missing or unreadable: $path\");\n}\n$loader->load($path, 'en');","handlingStrategy":"validation","validationCode":"$path = $resource;\nif (!is_string($path) || !is_file($path) || !is_readable($path)) {\n    throw new \\InvalidArgumentException(\"Unreadable CSV translation file: $path\");\n}","typeGuard":"function isReadableFile(mixed $r): bool { return is_string($r) && is_file($r) && is_readable($r); }","tryCatchPattern":"try {\n    $catalogue = $loader->load($path, 'en');\n} catch (Symfony\\Component\\Translation\\Exception\\NotFoundResourceException $e) {\n    $catalogue = new MessageCatalogue('en'); // fallback\n}","preventionTips":["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."],"tags":["csv","file-loader","translation","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}