twigphp/Twig · error · LogicException
You cannot use the "html_to_markdown" filter as…
Error message
You cannot use the "html_to_markdown" filter as league/html-to-markdown is not installed; try running "composer require league/html-to-markdown".
What it means
MarkdownExtension::htmlToMarkdown() is a static helper backing the html_to_markdown filter. It requires league/html-to-markdown's HtmlConverter class; if that package is not installed it throws a LogicException telling you to composer require it. Unlike the markdown_to_html side, no alternative library is accepted.
Solutions
- Run "composer require league/html-to-markdown".
- Guard usage: check class_exists(\League\HTMLToMarkdown\HtmlConverter::class) before enabling the filter in your extension config.
Example fix
// before
{{ body|html_to_markdown }}
// after (after running: composer require league/html-to-markdown)
{{ body|html_to_markdown }} Defensive patterns
Strategy: validation
Validate before calling
if (!class_exists(\League\HTMLToMarkdown\HtmlConverter::class)) {
// skip registering/enabling the html_to_markdown filter or fail fast with install instructions
} Try / catch
try {
$md = \Twig\Extra\Markdown\MarkdownExtension::htmlToMarkdown($html);
} catch (\LogicException $e) {
// league/html-to-markdown not installed; degrade gracefully
} Prevention
- Add league/html-to-markdown to composer.json's require section (not require-dev) if any template uses html_to_markdown.
- Check class_exists(\League\HTMLToMarkdown\HtmlConverter::class) in a health check or feature-flag setup.
- Note that league/commonmark alone is NOT sufficient for html_to_markdown — the two filters need different packages.
When it happens
Trigger: Using the {{ content|html_to_markdown }} filter (or calling MarkdownExtension::htmlToMarkdown directly, as tests do) in a project where league/html-to-markdown is absent.
Common situations: Installing twig/markdown-extra without league/html-to-markdown (they are separate optional packages); forgetting the dep in a production composer.json while present locally via require-dev; CI environments with --no-dev installs.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- You cannot use the "markdown_to_html" filter as no Markdown…
- The "format_list" filter requires the "IntlListFormatter"…
- Unable to format the given list
- The date format " " does not exist, known formats are: " ".
- The time format " " does not exist, known formats are: " ".
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/5dae0c8a693d332a.
Report an issue: GitHub.
Appendix: source
Thrown at extra/markdown-extra/MarkdownExtension.php:36
final class MarkdownExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('markdown_to_html', ['Twig\\Extra\\Markdown\\MarkdownRuntime', 'convert'], ['is_safe' => ['html']]),
new TwigFilter('html_to_markdown', [self::class, 'htmlToMarkdown']),
];
}
/**
* @internal
*/
public static function htmlToMarkdown(string $body, array $options = []): string
{
static $converters;
if (!class_exists(HtmlConverter::class)) {
throw new \LogicException('You cannot use the "html_to_markdown" filter as league/html-to-markdown is not installed; try running "composer require league/html-to-markdown".');
}
$options += [
'hard_break' => true,
'strip_tags' => true,
'remove_nodes' => 'head style',
];
if (!isset($converters[$key = serialize($options)])) {
$converters[$key] = new HtmlConverter($options);
}
return $converters[$key]->convert($body);
}
}
View on GitHub (pinned to a414c3a491)