headroomlabs-ai/headroom · error · ImportError
jinja2 is required for report generation. Install with: pip
Error message
jinja2 is required for report generation. Install with: pip install headroom[reports]
What it means
Raised by _get_jinja2_template() in the report generator when the jinja2 import fails while rendering a report. HTML report generation is an optional feature backed by the [reports] extra; the import is lazy so the error appears at render time, not at import of the module.
Source
Thrown at headroom/reporting/generator.py:23
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING, Any
from ..storage import create_storage
from ..utils import estimate_cost, format_cost
if TYPE_CHECKING:
pass
def _get_jinja2_template(template_str: str):
"""Lazily import jinja2 and create template."""
try:
from jinja2 import Template
return Template(template_str)
except ImportError as e:
raise ImportError(
"jinja2 is required for report generation. Install with: pip install headroom[reports]"
) from e
# HTML template embedded as string
REPORT_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Headroom Report - {{ generated_at }}</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}View on GitHub (pinned to 322425c43b)
Solutions
- Install the extra: pip install 'headroom[reports]'.
- Check for jinja2 in the deployment image: python -c "import jinja2".
- Disable report generation in configs for deployments that do not need it.
Example fix
# before html = generator.render() # ImportError: jinja2 required # after # pip install 'headroom[reports]' html = generator.render()
Defensive patterns
Strategy: fallback
Validate before calling
def jinja2_available() -> bool:
try:
import jinja2 # noqa: F401
return True
except ImportError:
return False
if not jinja2_available():
skip_report_generation() # or install check in deploy pipeline Type guard
def jinja2_available() -> bool:
try:
import jinja2 # noqa: F401
return True
except ImportError:
return False Try / catch
try:
html = generator.render()
except ImportError as e:
if 'jinja2' in str(e):
logger.warning('reports disabled: %s', e)
else:
raise Prevention
- Include the [reports] extra wherever report generation is enabled.
- Gate report generation behind a startup capability probe.
- Add 'python -c "import jinja2"' to your image build or preflight checks.
When it happens
Trigger: Calling the report generator's render/generate entry point that builds REPORT_TEMPLATE through _get_jinja2_template() without jinja2 installed.
Common situations: Base install of headroom used for proxying only, then someone enables report generation; CI image missing extras; jinja2 removed as a transitive dependency of another package.
Related errors
- numpy is required for EmbeddingScorer. Install with: pip ins
- EmbeddingScorer requires fastembed. Install with: pip instal
- EmbeddingScorer requires sentence-transformers. Install with
- No optimizer registered for '{key}'. Available: {available}
- httpx is required for Headroom Cloud mode: pip install httpx
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/26b15164935b6d54.
Report an issue: GitHub.