{"record":{"id":"1a6947e66e0edc9a","repo":"twigphp/Twig","slug":"a-block-chain-requires-at-least-one-template","errorCode":null,"errorMessage":"A block chain requires at least one template.","messagePattern":"A block chain requires at least one template\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/BlockChain.php","lineNumber":61,"sourceCode":"    ) {\n        foreach ($templates as $template) {\n            if (\\is_string($template)) {\n                $template = $env->load($template);\n            }\n            if (!$template instanceof TemplateWrapper) {\n                throw new \\TypeError(\\sprintf('Block chain templates must be strings or \"%s\" instances, \"%s\" given.', TemplateWrapper::class, get_debug_type($template)));\n            }\n\n            $template = $template->unwrap();\n            if (!$template->isOwnedBy($env)) {\n                throw new \\LogicException('A block chain cannot contain templates from different Twig environments.');\n            }\n\n            $this->templates[] = $template;\n        }\n\n        if (!$this->templates) {\n            throw new \\InvalidArgumentException('A block chain requires at least one template.');\n        }\n    }\n\n    /**\n     * @param array<string, mixed> $context\n     */\n    public function hasBlock(string $name, array $context = []): bool\n    {\n        $blocks = $this->fixed ? $this->blocks : $this->resolveBlocks($context + $this->context + $this->env->getGlobals());\n\n        return isset($blocks[$name]);\n    }\n\n    /**\n     * @param array<string, mixed> $context\n     *\n     * @return string[]\n     */","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/BlockChain.php#L43-L79","documentation":"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.","triggerScenarios":"new Twig\\BlockChain($env, []) or passing an empty array/iterator/generator that yields no templates (e.g. an empty glob of template names).","commonSituations":"Building the template list dynamically (theme discovery, plugin-provided templates) where all sources are absent; refactoring code that used to pass a default template.","solutions":["Ensure at least one template name or TemplateWrapper is in the list before constructing the chain.","Fall back to a default template when the dynamic collection is empty.","Guard with a count check and handle the empty case explicitly instead of constructing the chain."],"exampleFix":"// before\n$chain = new \\Twig\\BlockChain($env, $themes); // $themes may be []\n// after\nif (!$themes) { $themes = ['default_theme/base.html.twig']; }\n$chain = new \\Twig\\BlockChain($env, $themes);","handlingStrategy":"validation","validationCode":"if (count($templates) === 0) {\n    $templates = ['default_theme/base.html.twig'];\n}","typeGuard":"null","tryCatchPattern":"try {\n    $chain = new \\Twig\\BlockChain($env, $templates);\n} catch (\\InvalidArgumentException $e) {\n    $chain = new \\Twig\\BlockChain($env, [$defaultTemplate]);\n}","preventionTips":["Always include a default/fallback template in dynamically-built collections.","Check count($templates) > 0 before constructing the chain.","Log when a template discovery step yields nothing so the empty case is visible."],"tags":["php","twig","invalid-argument","empty-collection"],"backgroundTag":"empty-required-field","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}