headroomlabs-ai/headroom · error · ImportError
Reading .xlsx files requires openpyxl. Install it with: pip
Error message
Reading .xlsx files requires openpyxl. Install it with: pip install headroom-ai[spreadsheet]
What it means
Spreadsheet ingest needs the optional `openpyxl` package to read `.xlsx` workbooks, and it is not installed in the current environment. The library keeps spreadsheet parsers as an optional dependency to keep the base install lean, so this ImportError is the documented pointer to install the `spreadsheet` extra.
Source
Thrown at headroom/transforms/spreadsheet_ingest.py:34
from pathlib import Path
__all__ = ["load_spreadsheet"]
def _rows_to_csv(rows: list[list[object]]) -> str:
"""Render rows to CSV text, dropping fully empty trailing rows."""
buf = io.StringIO()
writer = csv.writer(buf)
for row in rows:
writer.writerow(["" if cell is None else cell for cell in row])
return buf.getvalue().strip("\n")
def _load_xlsx(path: Path) -> dict[str, str]:
try:
import openpyxl
except ImportError as e: # pragma: no cover - openpyxl ships in [dev]; defensive guard
raise ImportError(
"Reading .xlsx files requires openpyxl. "
"Install it with: pip install headroom-ai[spreadsheet]"
) from e
wb = openpyxl.load_workbook(path, read_only=True, data_only=True)
sheets: dict[str, str] = {}
try:
for ws in wb.worksheets:
rows = [list(r) for r in ws.iter_rows(values_only=True)]
text = _rows_to_csv(rows)
if text.strip():
sheets[ws.title] = text
finally:
wb.close()
return sheets
def _load_xls(View on GitHub (pinned to 322425c43b)
Solutions
- Install the extra: `pip install headroom-ai[spreadsheet]`
- Add the extra to your requirements/pyproject so environments are built with it: `headroom-ai[spreadsheet]` in dependencies, or the extra in a Dockerfile/CI requirements file
- If openpyxl is intentionally absent, pre-check the file type and skip or reject `.xlsx` inputs with your own message before calling ingest
Example fix
# before
$ pip install headroom-ai
sheets = ingest_spreadsheet(Path("report.xlsx"))
# after
$ pip install "headroom-ai[spreadsheet]"
sheets = ingest_spreadsheet(Path("report.xlsx")) Defensive patterns
Strategy: validation
Validate before calling
def xlsx_supported() -> bool:
try:
import openpyxl # noqa: F401
return True
except ImportError:
return False
if path.suffix.lower() == ".xlsx" and not xlsx_supported():
raise RuntimeError("this deployment cannot ingest .xlsx; install headroom-ai[spreadsheet]") Type guard
def can_read_xlsx() -> bool:
return importlib.util.find_spec("openpyxl") is not None Try / catch
try:
sheets = ingest_spreadsheet(path)
except ImportError as e:
if "openpyxl" in str(e):
raise RuntimeError("deploy fix: pip install headroom-ai[spreadsheet]") from e
raise Prevention
- Put headroom-ai[spreadsheet] in the base requirements for any service touching spreadsheets
- Fail fast at startup with an importlib availability probe if the extra is missing
- Bake the extra into Docker/CI images, not ad-hoc installs
When it happens
Trigger: Calling the ingest API with a `.xlsx` path (which routes to `_load_xlsx`) in an environment where `pip install headroom-ai` was run without the `[spreadsheet]` extra, so `import openpyxl` fails.
Common situations: New deployment or CI image built from a minimal requirements list; a Docker image that copied only the base package; upgrading headroom in a venv created before spreadsheet support was needed; local dev machine never given the extra.
Related errors
- Reading legacy .xls files requires xlrd. Install it with: pi
- MCP SDK not installed. Install with: pip install mcp
- Error: Memory eval dependencies not installed.
- Error: Memory eval V2 dependencies not installed.
- Error: MCP SDK not installed.
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/cfe7f490cd693219.
Report an issue: GitHub.