pola-rs/polars · error · NotImplementedError

unrecognized engine

Error message

unrecognized engine: {engine!r}

What it means

Polars' `read_excel`/spreadsheet reader only supports a fixed set of engines ('calamine', 'openpyxl', 'xlsx2csv', 'pyxlsb', 'ods'). After dispatching through the engine-specific reader functions, any engine value that did not match falls through to this final guard in `_initialise_spreadsheet_parser`, which raises `NotImplementedError`. It means the requested engine is not a known/supported backend name.

Solutions

  1. Set engine to one of the supported values: 'calamine' (default), 'openpyxl', 'xlsx2csv', 'pyxlsb', or 'ods'.
  2. Check spelling/case of the engine string exactly as listed in the polars docs.
  3. If the engine value comes from config, validate it against the supported set before calling read_excel.
  4. Install the dependency required for the chosen engine (e.g. pip install fastexcel for 'calamine').

Example fix

// before
pl.read_excel('data.xlsx', engine='xlsxwriter')
// after
pl.read_excel('data.xlsx', engine='calamine')  # or 'openpyxl', 'xlsx2csv', 'pyxlsb', 'ods'
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_ENGINES = {'calamine', 'openpyxl', 'xlsx2csv', 'pyxlsb', 'ods'}
if engine not in SUPPORTED_ENGINES:
    raise ValueError(f'engine must be one of {sorted(SUPPORTED_ENGINES)}, got {engine!r}')

Type guard

def is_valid_engine(engine: object) -> TypeGuard[str]:
    return isinstance(engine, str) and engine in {'calamine', 'openpyxl', 'xlsx2csv', 'pyxlsb', 'ods'}

Try / catch

try:
    df = pl.read_excel(path, engine=engine)
except NotImplementedError as e:
    log.error('Unsupported spreadsheet engine: %s', e)
    df = pl.read_excel(path, engine='calamine')

Prevention

When it happens

Trigger: Calling `pl.read_excel(..., engine='xlsxwriter')`, a misspelled engine like `'openpyl'`, or passing a non-string value; also occurs when a custom string is passed to `read_ods`/`read_xls` wrappers that share `_read_spreadsheet`.

Common situations: Typo in the engine name; copying example code from another library (e.g. pandas' 'openpyxl' vs polars' engine list); passing a config value read from a YAML/JSON file that holds an unsupported engine string; confusion between writer engines (xlsxwriter) and reader engines.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/c2e40f7b5809540f. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/io/spreadsheet/functions.py:902

        if reading_bytesio:
            source = source.getvalue()  # type: ignore[union-attr]
        elif isinstance(source, (BufferedReader, TextIOWrapper)):
            if "b" not in source.mode:
                msg = f"file {source.name!r} must be opened in binary mode"
                raise OSError(msg)
            elif (filename := source.name) and Path(filename).exists():
                source = filename
            else:
                source = source.read()

        parser = fastexcel.read_excel(source, **engine_options)
        sheets = [
            {"index": i + 1, "name": nm} for i, nm in enumerate(parser.sheet_names)
        ]
        return _read_spreadsheet_calamine, parser, sheets

    msg = f"unrecognized engine: {engine!r}"
    raise NotImplementedError(msg)


def _csv_buffer_to_frame(
    csv: StringIO,
    *,
    separator: str,
    read_options: dict[str, Any],
    schema_overrides: SchemaDict | None,
    drop_empty_rows: bool,
    drop_empty_cols: bool,
    raise_if_empty: bool,
) -> pl.DataFrame:
    """Translate StringIO buffer containing delimited data as a DataFrame."""
    # handle (completely) empty sheet data
    if csv.tell() == 0:
        return _empty_frame(raise_if_empty)

    # otherwise rewind the buffer and parse as csv

View on GitHub (pinned to fe841f959e)