pandas-dev/pandas · error · TypeError

where must be passed as a string, PyTablesExpr, or list-like

Error message

where must be passed as a string, PyTablesExpr, or list-like of PyTablesExpr

What it means

Raised by _validate_where in pandas.core.computation.pytables when the 'where' argument passed to PyTablesExpr (and thus to HDFStore.select / read_hdf) is not a str, not a PyTablesExpr, and not a list-like of those types. The validator explicitly allows str, PyTablesExpr, or is_list_like(w); anything else (dict, int, None used incorrectly, custom objects) is rejected with TypeError.

Source

Thrown at pandas/core/computation/pytables.py:548

    """
    Validate that the where statement is of the right type.

    The type may either be String, Expr, or list-like of Exprs.

    Parameters
    ----------
    w : String term expression, Expr, or list-like of Exprs.

    Returns
    -------
    where : The original where clause if the check was successful.

    Raises
    ------
    TypeError : An invalid data type was passed in for w (e.g. dict).
    """
    if not (isinstance(w, (PyTablesExpr, str)) or is_list_like(w)):
        raise TypeError(
            "where must be passed as a string, PyTablesExpr, "
            "or list-like of PyTablesExpr"
        )

    return w


class PyTablesExpr(expr.Expr):
    """
    Hold a pytables-like expression, comprised of possibly multiple 'terms'.

    Parameters
    ----------
    where : string term expression, PyTablesExpr, or list-like of PyTablesExprs
    queryables : a "kinds" map (dict of column name -> kind), or None if column
        is non-indexable
    encoding : an encoding that will encode the query terms

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Pass a string expression: store.select('df', where='a > 5').
  2. Pass a PyTablesExpr built once and reused: expr = pd.core.computation.pytables.PyTablesExpr('a > 5', queryables=...); store.select('df', where=expr).
  3. Pass a list-like of expressions: where=['a > 5', 'b < 3'].
  4. To select all rows, omit where entirely: store.select('df').
  5. If you have a boolean mask, read the frame first then apply it: df[mask].

Example fix

# before
store.select('df', where={'a': 5})  # TypeError: where must be passed as a string ...

# after (string)
store.select('df', where='a == 5')
# after (omit where to select all)
store.select('df')
# after (boolean mask in pandas)
df = store.get('df')
df[df['a'] == 5]
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd
from pandas.core.computation.pytables import PyTablesExpr
from pandas.core.dtypes.common import is_list_like

def assert_valid_where(w):
    if not (isinstance(w, (str, PyTablesExpr)) or is_list_like(w)):
        raise TypeError('where must be str, PyTablesExpr, or list-like of those')
    return w

Type guard

import pandas as pd
from pandas.core.computation.pytables import PyTablesExpr
from pandas.core.dtypes.common import is_list_like

def is_valid_where(w) -> bool:
    if w is None:
        return False
    return isinstance(w, (str, PyTablesExpr)) or is_list_like(w)

Try / catch

try:
    store.select('df', where=where)
except TypeError as e:
    if 'where must be passed as a string' in str(e):
        if where is None:
            store.select('df')
        else:
            store.select('df', where=str(where))
    else:
        raise

Prevention

When it happens

Trigger: store.select('df', where={'a': 5}); store.select('df', where=123); store.select('df', where=None) when None is not a valid where; passing a numpy boolean array directly instead of an expression.

Common situations: Confusing the pytables where API with the DataFrame[...] boolean-mask API; passing a dict of conditions; passing raw arrays or scalars; assuming None means 'no filter' (it does not - omit the where argument instead).

Related errors


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