twigphp/Twig · error · Twig\Error\LoaderError
Template " " does not exist.
Error message
Template "%s" does not exist.
What it means
A custom Twig LoaderError thrown by a loader's getSourceContext() when the storage backend (here a database via dbh/getValue) returns no source for the requested template name. Twig loaders must throw LoaderError from getSourceContext when a template cannot be located, so the engine (or exists()) can report the missing template clearly.
Solutions
- Verify the template name exists in the storage backend for the configured connection.
- Check $this->dbh connection settings and that getValue() queries the right table/column.
- Call $twig->getLoader()->exists($name) (or exists()) before rendering and fall back to a default template.
- Ensure templates are seeded/deployed to the backend before referencing them.
Example fix
// before
return $twig->render('emails/welcome.twig', $ctx);
// after
if ($twig->getLoader()->exists('emails/welcome.twig')) {
return $twig->render('emails/welcome.twig', $ctx);
}
return $twig->render('emails/default.twig', $ctx); Defensive patterns
Strategy: try-catch
Validate before calling
if (!$loader->exists($templateName)) { /* fallback or log */ } Try / catch
try {
$html = $twig->render($name, $ctx);
} catch (\Twig\Error\LoaderError $e) {
$logger->warning('Template missing: ' . $name);
$html = $twig->render('fallback.twig', $ctx);
} Prevention
- Check loader->exists() for dynamic/user-supplied template names before rendering.
- Seed template rows into the DB as part of deployment migrations.
- Log the requested name in the loader's exists()/getSourceContext() to catch naming drift.
- Keep template names centralized in constants/services to avoid typos.
When it happens
Trigger: Calling $twig->render('name') or $loader->getSourceContext('name') where the lookup row for 'name' is absent in the data source (getValue returns false); a stale/cached template name referenced by an include/extends whose row was deleted.
Common situations: Database-backed template storage where templates were migrated or purged; typo in template name; deploying code referencing templates not yet seeded into the DB; wrong table/connection configured for the loader.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Unable to find one of the following templates
- Template " " is not defined .
- 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/5b41ec20473499bd.
Report an issue: GitHub.
Appendix: source
Thrown at doc/recipes.rst:426
We have created a simple ``templates`` table that hosts two templates:
``base.html.twig`` and ``index.html.twig``.
Now, let's define a loader able to use this database::
class DatabaseTwigLoader implements \Twig\Loader\LoaderInterface
{
protected $dbh;
public function __construct(PDO $dbh)
{
$this->dbh = $dbh;
}
public function getSourceContext(string $name): Source
{
if (false === $source = $this->getValue('source', $name)) {
throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
}
return new \Twig\Source($source, $name);
}
public function exists(string $name)
{
return $name === $this->getValue('name', $name);
}
public function getCacheKey(string $name): string
{
return $name;
}
public function isFresh(string $name, int $time): bool
{
if (false === $lastModified = $this->getValue('last_modified', $name)) {View on GitHub (pinned to a414c3a491)