symfony/translation · error · RuntimeException
No loader is registered for the
Error message
No loader is registered for the "%s" format when loading the "%s" resource.
What it means
Thrown by Symfony\Component\Translation\Translator when catalogue initialisation encounters a registered translation resource whose format has no loader registered in $this->loaders, and the resource is a string path. RuntimeException includes both the format and the resource path.
Solutions
- Register a loader for the format: $translator->addLoader('yaml', new YamlFileLoader())
- Install the required package (e.g. symfony/yaml for yaml resources, symfony/twig or xml extension for xliff)
- Check config/packages/translation.yaml loaders wiring in full-framework apps
- Remove stale addResource() calls for formats you no longer support
Example fix
// before
$translator->addResource('yaml', 'messages.fr.yaml', 'fr');
// after
use Symfony\Component\Translation\Loader\YamlFileLoader;
$translator->addLoader('yaml', new YamlFileLoader());
$translator->addResource('yaml', 'messages.fr.yaml', 'fr'); Defensive patterns
Strategy: try-catch
Validate before calling
foreach ($resources as [$format, $path]) {
if (!isset($loaders[$format])) {
throw new \RuntimeException("Register a loader for format '{$format}' before adding resources.");
}
} Try / catch
try {
$translator->trans('key', [], 'messages', 'fr');
} catch (RuntimeException $e) {
if (str_contains($e->getMessage(), 'No loader is registered')) {
// register the missing loader and retry
}
} Prevention
- Always pair addResource() with a matching addLoader()
- Keep symfony/yaml (and other format packages) in composer.json
- In full-framework apps, do not remove default translation loader DI definitions
When it happens
Trigger: addResource('yaml', '/path/messages.fr.yaml', 'fr') (or via translation resource config) called without first adding a loader for that format via addLoader().
Common situations: Using a format whose loader package is missing (e.g. symfony/translation not configured with YamlFileLoader or XliffFileLoader), custom resource formats without a matching loader, or framework.translator loaders removed from DI.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- No loader is registered for the
- The scheme "null" is not supported by this provider.
- Provider " " not found. Available: " ".
- The scheme is not supported by any provider.
- The " ()" method cannot be called as the wrapped translator…
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/b19e336984fbdeef.
Report an issue: GitHub.
Appendix: source
Thrown at Translator.php:371
}
private function getCatalogueCachePath(string $locale): string
{
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('xxh128', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
}
/**
* @internal
*/
protected function doLoadCatalogue(string $locale): void
{
$this->catalogues[$locale] = new MessageCatalogue($locale);
if (isset($this->resources[$locale])) {
foreach ($this->resources[$locale] as $resource) {
if (!isset($this->loaders[$resource[0]])) {
if (\is_string($resource[1])) {
throw new RuntimeException(\sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1]));
}
throw new RuntimeException(\sprintf('No loader is registered for the "%s" format.', $resource[0]));
}
$this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
}
}
}
private function loadFallbackCatalogues(string $locale): void
{
$current = $this->catalogues[$locale];
foreach ($this->computeFallbackLocales($locale) as $fallback) {
if (!isset($this->catalogues[$fallback])) {
$this->initializeCatalogue($fallback);
}
View on GitHub (pinned to ae9e8a51bc)