twigphp/Twig · error · InvalidArgumentException

A block chain requires at least one template.

Error message

A block chain requires at least one template.

What it means

A BlockChain must contain at least one template to be useful; constructing it with an empty iterable leaves $this->templates empty, so the constructor throws this InvalidArgumentException. The chain has nothing to search for blocks otherwise, so the library rejects it eagerly.

Solutions

  1. Ensure at least one template name or TemplateWrapper is in the list before constructing the chain.
  2. Fall back to a default template when the dynamic collection is empty.
  3. Guard with a count check and handle the empty case explicitly instead of constructing the chain.

Example fix

// before
$chain = new \Twig\BlockChain($env, $themes); // $themes may be []
// after
if (!$themes) { $themes = ['default_theme/base.html.twig']; }
$chain = new \Twig\BlockChain($env, $themes);
Defensive patterns

Strategy: validation

Validate before calling

if (count($templates) === 0) {
    $templates = ['default_theme/base.html.twig'];
}

Type guard

null

Try / catch

try {
    $chain = new \Twig\BlockChain($env, $templates);
} catch (\InvalidArgumentException $e) {
    $chain = new \Twig\BlockChain($env, [$defaultTemplate]);
}

Prevention

When it happens

Trigger: new Twig\BlockChain($env, []) or passing an empty array/iterator/generator that yields no templates (e.g. an empty glob of template names).

Common situations: Building the template list dynamically (theme discovery, plugin-provided templates) where all sources are absent; refactoring code that used to pass a default template.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/BlockChain.php:61

    ) {
        foreach ($templates as $template) {
            if (\is_string($template)) {
                $template = $env->load($template);
            }
            if (!$template instanceof TemplateWrapper) {
                throw new \TypeError(\sprintf('Block chain templates must be strings or "%s" instances, "%s" given.', TemplateWrapper::class, get_debug_type($template)));
            }

            $template = $template->unwrap();
            if (!$template->isOwnedBy($env)) {
                throw new \LogicException('A block chain cannot contain templates from different Twig environments.');
            }

            $this->templates[] = $template;
        }

        if (!$this->templates) {
            throw new \InvalidArgumentException('A block chain requires at least one template.');
        }
    }

    /**
     * @param array<string, mixed> $context
     */
    public function hasBlock(string $name, array $context = []): bool
    {
        $blocks = $this->fixed ? $this->blocks : $this->resolveBlocks($context + $this->context + $this->env->getGlobals());

        return isset($blocks[$name]);
    }

    /**
     * @param array<string, mixed> $context
     *
     * @return string[]
     */

View on GitHub (pinned to a414c3a491)