{"record":{"id":"1998411bacd4767a","repo":"symfony/translation","slug":"this-is-not-a-local-file-s-qtfileloader","errorCode":null,"errorMessage":"This is not a local file \"%s\".","messagePattern":"This is not a local file \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidResourceException","httpStatus":null,"severity":"error","filePath":"Loader/QtFileLoader.php","lineNumber":35,"sourceCode":"use Symfony\\Component\\Translation\\Exception\\NotFoundResourceException;\nuse Symfony\\Component\\Translation\\Exception\\RuntimeException;\nuse Symfony\\Component\\Translation\\MessageCatalogue;\n\n/**\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","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Loader/QtFileLoader.php#L17-L53","documentation":"QtFileLoader only reads local filesystem resources; stream_is_local() rejects remote URLs/wrappers such as http:// or ftp://, since XmlUtils::loadFile requires a local path. It throws InvalidResourceException with the offending resource path.","triggerScenarios":"load() called with a non-local stream target, e.g. 'https://example.com/messages.ts', 'ftp://...', or a custom stream wrapper — raised in testLoad paths.","commonSituations":"Configuring the translation resource path from a CDN/remote origin, passing a URL built from environment config, trying to load bundles straight from object storage.","solutions":["Download the .ts file to a local temp path (file_get_contents/curl) and pass the local path to load().","Mount or sync remote translation files locally as part of deployment.","If resources truly must be remote, write a custom loader that streams content and parses via a DOMDocument loaded from a string.","Fix config that interpolates a base URL into the resource path."],"exampleFix":"// before\n$loader->load('https://cdn.example.com/messages.fr.ts', 'fr');\n// after\n$tmp = sys_get_temp_dir().'/messages.fr.ts';\nfile_put_contents($tmp, file_get_contents('https://cdn.example.com/messages.fr.ts'));\n$loader->load($tmp, 'fr');","handlingStrategy":"validation","validationCode":"if (!stream_is_local($resource)) {\n    throw new \\RuntimeException(sprintf('Translation resource must be local, got: %s', $resource));\n}","typeGuard":"function isLocalFilePath(mixed $resource): bool {\n    return is_string($resource) && stream_is_local($resource) && !preg_match('#^[a-z][a-z0-9+.-]*://#i', $resource);\n}","tryCatchPattern":"try {\n    $catalogue = $loader->load($resource, $locale);\n} catch (InvalidResourceException $e) {\n    if (str_contains($e->getMessage(), 'not a local file')) {\n        $local = downloadToTemp($resource);\n        $catalogue = $loader->load($local, $locale);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Keep translation files on local disk; sync remote sources at deploy time","Do not interpolate URLs into resource paths from env config","Validate resource paths against a whitelist of local directories","Document that loaders require local streams"],"tags":["qt","translation","stream-wrapper","file-path"],"backgroundTag":"invalid-url-format","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"}