pandas-dev/pandas · error · KeyError

Invalid engine '{engine}' passed, valid engines are {valid_e

Error message

Invalid engine '{engine}' passed, valid engines are {valid_engines}

What it means

Raised by _check_engine (pandas/core/computation/eval.py:67) as a KeyError when the `engine` argument to pd.eval / DataFrame.eval / DataFrame.query is not one of the registered engines (the keys of ENGINES, typically 'numexpr' and 'python'). Validation happens up front so no partial evaluation is attempted.

Source

Thrown at pandas/core/computation/eval.py:67

    KeyError
      * If an invalid engine is passed.
    ImportError
      * If numexpr was requested but doesn't exist.

    Returns
    -------
    str
        Engine name.
    """
    from pandas.core.computation.check import NUMEXPR_INSTALLED
    from pandas.core.computation.expressions import USE_NUMEXPR

    if engine is None:
        engine = "numexpr" if USE_NUMEXPR else "python"

    if engine not in ENGINES:
        valid_engines = list(ENGINES.keys())
        raise KeyError(
            f"Invalid engine '{engine}' passed, valid engines are {valid_engines}"
        )

    # TODO: validate this in a more general way (thinking of future engines
    # that won't necessarily be import-able)
    # Could potentially be done on engine instantiation
    if engine == "numexpr" and not NUMEXPR_INSTALLED:
        raise ImportError(
            "'numexpr' is not installed or an unsupported version. Cannot use "
            "engine='numexpr' for query/eval if 'numexpr' is not installed"
        )

    return engine


def _check_parser(parser: str) -> None:
    """
    Make sure a valid parser is passed.

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use a valid engine: 'python' (always available) or 'numexpr' (if installed).
  2. Omit engine to let pandas choose the default ('numexpr' if available else 'python').
  3. Validate config-supplied engine names against `pandas.core.computation.engines.ENGINES.keys()` before passing.

Example fix

# before
df.query('x > 0', engine='cython')

# after
df.query('x > 0', engine='python')
Defensive patterns

Strategy: validation

Validate before calling

from pandas.core.computation.engines import ENGINES

def validate_engine(engine):
    if engine is not None and engine not in ENGINES:
        raise KeyError(f"Invalid engine '{engine}', valid: {list(ENGINES)}")
    return engine

Type guard

from pandas.core.computation.engines import ENGINES

def is_valid_engine(engine) -> bool:
    return engine is None or engine in ENGINES

Try / catch

try:
    result = df.query('x > 0', engine=engine)
except KeyError as e:
    if 'Invalid engine' in str(e):
        result = df.query('x > 0', engine='python')
    else:
        raise

Prevention

When it happens

Trigger: `df.query('x > 0', engine='cython')`, `pd.eval('1+1', engine='numpy')`, a typo like `engine='numexpr2'`, or passing a non-string.

Common situations: Typos, guessing an engine name, stale code referencing a removed/renamed engine, or dynamic engine selection with an unvalidated config value.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/4de4e78c3d0e888d. Report an issue: GitHub.