twigphp/Twig · error · LogicException

Test " " is already registered.

Error message

Test "%s" is already registered.

What it means

StagingExtension stores user-registered TwigTests (the `is ...` tests) by name. Twig throws this LogicException when addTest is called with a test whose name is already taken, since test names must be unique for expression resolution to be deterministic.

Solutions

  1. Rename your custom test to a unique name, or drop the duplicate registration.
  2. Check which extension already defines the test with that name and pick a single source of truth.
  3. Guard registration code with a container/service singleton or a static flag so it runs once.

Example fix

// before
$twig->addTest(new TwigTest('bundle', fn() => true));
$twig->addTest(new TwigTest('bundle', fn() => false)); // 'bundle' already registered

// after
$twig->addTest(new TwigTest('my_bundle', fn() => true));
Defensive patterns

Strategy: try-catch

Validate before calling

$knownTests = array_column($twig->getTests() ?? [], null);
if (array_key_exists($test->getName(), (array) $knownTests)) { /* skip or rename */ }

Try / catch

try { $twig->addTest($test); } catch (\LogicException $e) {
    if (str_contains($e->getMessage(), 'is already registered')) { /* duplicate, skip */ }
    else { throw $e; }
}

Prevention

When it happens

Trigger: Calling $twig->addTest(new TwigTest('foo', ...)) twice, or adding two tests with the same name — e.g. two extensions both defining a test named 'same', or a custom test colliding with one from a core extension.

Common situations: Installing two bundles/extensions exporting the same test name; registering the same test in a shared bootstrap executed twice; adding a test whose name collides with a built-in like 'empty' or 'null'.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/Extension/StagingExtension.php:90

    public function addTokenParser(TokenParserInterface $parser): void
    {
        if (isset($this->tokenParsers[$parser->getTag()])) {
            throw new \LogicException(\sprintf('Tag "%s" is already registered.', $parser->getTag()));
        }

        $this->tokenParsers[$parser->getTag()] = $parser;
    }

    public function getTokenParsers(): array
    {
        return $this->tokenParsers;
    }

    public function addTest(TwigTest $test): void
    {
        if (isset($this->tests[$test->getName()])) {
            throw new \LogicException(\sprintf('Test "%s" is already registered.', $test->getName()));
        }

        $this->tests[$test->getName()] = $test;
    }

    public function getTests(): array
    {
        return $this->tests;
    }
}

View on GitHub (pinned to a414c3a491)