{"record":{"id":"0911e549588344b5","repo":"symfony/translation","slug":"file-s-not-found-qtfileloader","errorCode":null,"errorMessage":"File \"%s\" not found.","messagePattern":"File \"(.+?)\" not found\\.","errorType":"exception","errorClass":"NotFoundResourceException","httpStatus":null,"severity":"error","filePath":"Loader/QtFileLoader.php","lineNumber":39,"sourceCode":"/**\n * QtFileLoader loads translations from QT Translations XML files.\n *\n * @author Benjamin Eberlei <kontakt@beberlei.de>\n */\nclass QtFileLoader implements LoaderInterface\n{\n    public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue\n    {\n        if (!class_exists(XmlUtils::class)) {\n            throw new RuntimeException('Loading translations from the QT format requires the Symfony Config component.');\n        }\n\n        if (!stream_is_local($resource)) {\n            throw new InvalidResourceException(\\sprintf('This is not a local file \"%s\".', $resource));\n        }\n\n        if (!file_exists($resource)) {\n            throw new NotFoundResourceException(\\sprintf('File \"%s\" not found.', $resource));\n        }\n\n        try {\n            $dom = XmlUtils::loadFile($resource);\n        } catch (\\InvalidArgumentException $e) {\n            throw new InvalidResourceException(\\sprintf('Unable to load \"%s\".', $resource), $e->getCode(), $e);\n        }\n\n        $internalErrors = libxml_use_internal_errors(true);\n        libxml_clear_errors();\n\n        $xpath = new \\DOMXPath($dom);\n        $nodes = $xpath->evaluate('//TS/context/name[text()=\"'.$domain.'\"]');\n\n        $catalogue = new MessageCatalogue($locale);\n        if (1 == $nodes->length) {\n            $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');\n            foreach ($translations as $translation) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Loader/QtFileLoader.php#L21-L57","documentation":"QtFileLoader checks file_exists() after confirming the resource is a local stream; a missing file raises NotFoundResourceException naming the path. This is a distinct, catchable signal that the translation catalogue file simply does not exist.","triggerScenarios":"load() with a local path that does not exist — wrong directory in the translator's resource loader config, locale/domain file naming mismatch (e.g. messages.fr.ts absent), file deleted or never deployed.","commonSituations":"Per-locale files not generated for new languages, .gitignore excluding translation artifacts, path typos or case-sensitivity differences on Linux, container volumes missing the translations directory.","solutions":["Check the exact path exists: `ls -l <resource>`; watch for case-sensitivity on Linux.","Ensure your build/export step generates .ts files for every supported locale.","Fix the resources path passed to the translator (Translator::addResource or loader config).","Add a existence check with file_exists() before addResource to fail fast with a clearer app-level message."],"exampleFix":"// before\n$translator->addResource('qt', '/app/translations/messages.fr.ts', 'fr'); // file absent\n// after\n$file = '/app/translations/messages.fr.ts';\nif (!is_file($file)) {\n    throw new \\RuntimeException(\"Translation file missing: $file\");\n}\n$translator->addResource('qt', $file, 'fr');","handlingStrategy":"validation","validationCode":"if (!is_file($resource)) {\n    throw new \\RuntimeException(sprintf('Translation file does not exist: %s (dir listing: %s)', $resource, implode(',', (array) @glob(dirname($resource).'/*'))));\n}","typeGuard":"function fileExistsCaseSensitive(string $path): bool {\n    return is_file($path) && basename($path) === basename(glob(dirname($path).'/'.basename($path), GLOB_NOCHECK)[0] ?? $path);\n}","tryCatchPattern":"try {\n    $catalogue = $loader->load($resource, $locale);\n} catch (NotFoundResourceException $e) {\n    error_log('Missing translation file: '.$e->getMessage());\n    $catalogue = new MessageCatalogue($locale); // or fall back to default locale\n}","preventionTips":["Generate .ts files for every supported locale in CI","Use absolute, case-correct paths; test on a case-sensitive filesystem","Add file_exists assertions before addResource in bootstrap","Do not gitignore build-generated translation artifacts you deploy"],"tags":["qt","translation","file-not-found","path"],"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"}