twigphp/Twig · error · LoaderError

Template " " is not defined.

Error message

Template "%s" is not defined.

What it means

ArrayLoader::getSourceContext throws a LoaderError when asked for the source of a template name that was never set on the in-memory templates array. ArrayLoader only knows templates registered via setTemplate() or the constructor, so any unknown name fails immediately.

Solutions

  1. Register the template: $loader->setTemplate('name', $source) or include it in the ArrayLoader constructor array.
  2. Check the name for typos and exact-case match against registered keys.
  3. Guard with $loader->exists($name) before calling getSourceContext.
  4. If templates should come from disk, use FilesystemLoader instead of ArrayLoader.

Example fix

// before
$loader = new ArrayLoader();
echo $twig->render('index.html');

// after
$loader = new ArrayLoader(['index.html' => '<h1>Hi</h1>']);
echo $twig->render('index.html');
Defensive patterns

Strategy: try-catch

Validate before calling

if (!$loader->exists($name)) {
    throw new \RuntimeException("Template '{$name}' is not registered in the ArrayLoader");
}

Try / catch

try {
    $source = $loader->getSourceContext($name);
} catch (\Twig\Error\LoaderError $e) {
    log("Unknown template '{$name}': registered keys: ".implode(', ', array_keys($loader->getCacheKeys ? $loader->getCacheKeys() : [])));
    throw $e;
}

Prevention

When it happens

Trigger: Calling $loader->getSourceContext('name') (directly or via $twig->load()/render()) for a name not passed to the ArrayLoader constructor or setTemplate(). Called in tests like testGetSourceContextWhenTemplateDoesNotExist.

Common situations: Typos in template names passed to $twig->render(); forgetting to register a template in the loader before rendering; environment switches (dev registers templates, prod doesn't); refactors renaming template keys without updating render calls.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/a9936df4aafc9268. Report an issue: GitHub.

Appendix: source

Thrown at src/Loader/ArrayLoader.php:47

final class ArrayLoader implements LoaderInterface
{
    /**
     * @param array $templates An array of templates (keys are the names, and values are the source code)
     */
    public function __construct(
        private array $templates = [],
    ) {
    }

    public function setTemplate(string $name, string $template): void
    {
        $this->templates[$name] = $template;
    }

    public function getSourceContext(string $name): Source
    {
        if (!isset($this->templates[$name])) {
            throw new LoaderError(\sprintf('Template "%s" is not defined.', $name));
        }

        return new Source($this->templates[$name], $name);
    }

    public function exists(string $name): bool
    {
        return isset($this->templates[$name]);
    }

    public function getCacheKey(string $name): string
    {
        if (!isset($this->templates[$name])) {
            throw new LoaderError(\sprintf('Template "%s" is not defined.', $name));
        }

        return $name.':'.$this->templates[$name];
    }

View on GitHub (pinned to a414c3a491)