twigphp/Twig · error · RuntimeError
The " " extension is not enabled.
Error message
The "%s" extension is not enabled.
What it means
ExtensionSet::getExtension looks up a registered extension by its fully-qualified class name and throws this RuntimeError when no extension of that class has been added to the environment. Consumers (e.g. tests, internals, or code fetching an extension to tweak it) call getExtension to retrieve an instance; the class-string lookup is exact after ltrim of leading backslashes.
Solutions
- Register the extension first: `$twig->addExtension(new SomeExtension())` (or via the Symfony bundle config) before calling getExtension().
- Check with `$twig->hasExtension(SomeExtension::class)` before retrieving, and handle the negative case.
- Verify the exact fully-qualified class name matches what was registered (namespace changes after refactor).
- If the extension is optional, guard the lookup and skip dependent logic when it is absent.
Example fix
// before (PHP) $ext = $twig->getExtension(DebugExtension::class); // after $twig->addExtension(new DebugExtension()); $ext = $twig->getExtension(DebugExtension::class);
Defensive patterns
Strategy: validation
Validate before calling
// PHP, before fetching an extension
$cls = DebugExtension::class;
if (!$twig->hasExtension($cls)) {
$twig->addExtension(new $cls());
}
$ext = $twig->getExtension($cls); Try / catch
try {
$ext = $twig->getExtension(SomeExtension::class);
} catch (\Twig\Error\RuntimeError $e) {
if (str_contains($e->getMessage(), 'extension is not enabled')) {
// register lazily or degrade the feature that depends on it
} else { throw $e; }
} Prevention
- Centralize environment bootstrap so every needed addExtension() call happens in one place
- Check hasExtension() before getExtension() for optional extensions
- After renaming an extension class, update all getExtension(<FQCN>) call sites
- In tests, use setUp() to register extensions before any code fetches them
When it happens
Trigger: Calling `$environment->getExtension(SomeExtension::class)` (or `$env->hasExtension`-style flows that route through ExtensionSet) when `addExtension()` / the constructor never registered that class. Also triggered by leading-backslash mismatches being resolved, but the extension truly absent — e.g. in testMultipleRegistrations the extension under test was never added.
Common situations: Tests fetching an extension before registering it; an extension conditionally registered (feature-flagged) but queried unconditionally; refactoring renamed the extension class so the old FQCN no longer matches; provider bundle not registered in a Symfony app before `$env->getExtension()`.
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
- Tag " " is already registered.
- Test " " is already registered.
- Unable to register extension
- Unable to register extension
- Unable to add function
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/2f64074826ed845b.
Report an issue: GitHub.
Appendix: source
Thrown at src/ExtensionSet.php:92
$this->staging = new StagingExtension();
}
public function initRuntime(): void
{
$this->runtimeInitialized = true;
}
public function hasExtension(string $class): bool
{
return isset($this->extensions[ltrim($class, '\\')]);
}
public function getExtension(string $class): ExtensionInterface
{
$class = ltrim($class, '\\');
if (!isset($this->extensions[$class])) {
throw new RuntimeError(\sprintf('The "%s" extension is not enabled.', $class));
}
return $this->extensions[$class];
}
/**
* @param ExtensionInterface[] $extensions
*/
public function setExtensions(array $extensions): void
{
foreach ($extensions as $extension) {
$this->addExtension($extension);
}
}
/**
* @return ExtensionInterface[]
*/View on GitHub (pinned to a414c3a491)