twigphp/Twig · error · LoaderError
Template " " is not defined .
Error message
Template "%s" is not defined%s.
What it means
ChainLoader tries each registered loader in order when fetching a template's source. If every loader throws a LoaderError, it aggregates their messages and throws this LoaderError listing the name and the per-loader failure reasons (when any loader actually raised an error rather than just returning false from exists()).
Solutions
- Check the aggregated message for each loader's reason and fix the underlying loader misconfiguration.
- Register the template or add the correct path with addPath() to an appropriate loader.
- Verify the template name including its @Namespace/ prefix spelling.
Example fix
// before
$loader->addLoader(new FilesystemLoader('/wrong/path'));
$chain->getSourceContext('index.html.twig');
// after
$fs = new FilesystemLoader('/correct/templates');
$chain->addLoader($fs); // path that actually contains index.html.twig
$chain->getSourceContext('index.html.twig'); Defensive patterns
Strategy: try-catch
Validate before calling
foreach ($names as $name) { if (!$chain->exists($name)) { /* handle missing before getSourceContext */ } } Type guard
function chainHas(Twig\Loader\ChainLoader $chain, string $name): bool { try { $chain->getSourceContext($name); return true; } catch (Twig\Error\LoaderError $e) { return false; } } Try / catch
try { $src = $chain->getSourceContext($name); } catch (Twig\Error\LoaderError $e) { // message lists per-loader reasons; log $e->getMessage() and fall back } Prevention
- Call exists() before getSourceContext
- Keep loader paths verified in bootstrap/config tests
- Log the aggregated loader reasons to spot misconfiguration early
When it happens
Trigger: Calling getSourceContext($name) when no loader in the chain can find $name — e.g. template never created on disk, wrong namespace prefix, or loaders configured with wrong paths.
Common situations: Typos in template names; forgetting @namespace/ prefix when using namespaced paths; templates missing from all configured filesystem paths; load order pushing an intended loader after a failing one.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Unable to find one of the following templates
- Template " " does not exist.
- Template " " is not defined.
- Template " " is not defined.
- There are no registered paths for namespace
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/814bc07997890614.
Report an issue: GitHub.
Appendix: source
Thrown at src/Loader/ChainLoader.php:77
}
public function getSourceContext(string $name): Source
{
$exceptions = [];
foreach ($this->getLoaders() as $loader) {
if (!$loader->exists($name)) {
continue;
}
try {
return $loader->getSourceContext($name);
} catch (LoaderError $e) {
$exceptions[] = $e->getMessage();
}
}
throw new LoaderError(\sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
public function exists(string $name): bool
{
if (isset($this->hasSourceCache[$name])) {
return $this->hasSourceCache[$name];
}
foreach ($this->getLoaders() as $loader) {
if ($loader->exists($name)) {
return $this->hasSourceCache[$name] = true;
}
}
return $this->hasSourceCache[$name] = false;
}
public function getCacheKey(string $name): stringView on GitHub (pinned to a414c3a491)