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

  1. Register a loader for the format: $translator->addLoader('yaml', new YamlFileLoader())
  2. Install the required package (e.g. symfony/yaml for yaml resources, symfony/twig or xml extension for xliff)
  3. Check config/packages/translation.yaml loaders wiring in full-framework apps
  4. 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

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


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)