symfony/translation · error · InvalidResourceException
This is neither a file nor an XLIFF string
Error message
This is neither a file nor an XLIFF string "%s".
What it means
The resource is a local, existing path but is neither a regular file nor an XML string — typically a directory — so the loader throws InvalidResourceException. is_file() distinguishes regular files from directories and special files.
Solutions
- Pass a single .xlf/.xliff file path, not a directory.
- Iterate the directory yourself (glob('translations/*.xlf')) and call load() per file.
- Validate with is_file($resource) before calling load().
Example fix
// before
$loader->load('translations/', 'en'); // directory
// after
foreach (glob('translations/*.xlf') as $file) {
$loader->load($file, 'en');
} Defensive patterns
Strategy: validation
Validate before calling
if (!is_file($resource) && !str_starts_with(ltrim((string) $resource), '<?xml')) {
throw new \InvalidArgumentException(sprintf('Expected an XLIFF file, got: %s', $resource));
} Try / catch
try {
$catalogue = $loader->load($resource, $locale);
} catch (InvalidResourceException $e) {
if (str_contains($e->getMessage(), 'neither a file nor an XLIFF string')) {
// you probably passed a directory; enumerate files instead
}
} Prevention
- Pass file paths, never directory paths, to the loader.
- Use glob()/Finder to expand directories into per-file load calls.
- Add a unit test asserting configured resource paths are files.
When it happens
Trigger: Passing a directory path (e.g. the translations folder itself) as $resource to XliffFileLoader::load().
Common situations: Configuration mistake where a directory configured for translation lookup is fed to the loader directly instead of individual files.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Loading translations from the Xliff format requires the…
- This is not a local file
- File " " not found.
- Unable to load
- Invalid resource provided
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/4461b202f3e67baa.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/XliffFileLoader.php:48
class XliffFileLoader implements LoaderInterface
{
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
{
if (!class_exists(XmlUtils::class)) {
throw new RuntimeException('Loading translations from the Xliff format requires the Symfony Config component.');
}
if (!$this->isXmlString($resource)) {
if (!stream_is_local($resource)) {
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource)) {
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
if (!is_file($resource)) {
throw new InvalidResourceException(\sprintf('This is neither a file nor an XLIFF string "%s".', $resource));
}
}
try {
if ($this->isXmlString($resource)) {
$dom = XmlUtils::parse($resource);
} else {
$dom = XmlUtils::loadFile($resource);
}
} catch (\InvalidArgumentException|XmlParsingException|InvalidXmlException $e) {
throw new InvalidResourceException(\sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e);
}
if ($errors = XliffUtils::validateSchema($dom)) {
throw new InvalidResourceException(\sprintf('Invalid resource provided: "%s"; Errors: ', $resource).XliffUtils::getErrorsAsString($errors));
}
$catalogue = new MessageCatalogue($locale);View on GitHub (pinned to ae9e8a51bc)