reflex-dev/reflex · error · ValueError

Cannot pass in both a pandas dataframe and columns to the da

Error message

Cannot pass in both a pandas dataframe and columns to the data_editor component.

What it means

When data_editor receives a pandas DataFrame, it auto-generates columns from the dataframe; passing explicit columns as well is ambiguous and rejected.

Source

Thrown at packages/reflex-components-dataeditor/src/reflex_components_dataeditor/dataeditor.py:531

        columns = props.get("columns", [])
        data = props.get("data", [])
        rows = props.get("rows")

        # If rows is not provided, determine from data.
        if rows is None:
            if isinstance(data, Var) and not isinstance(data, ArrayVar):
                msg = "DataEditor data must be an ArrayVar if rows is not provided."
                raise ValueError(msg)

            props["rows"] = data.length() if isinstance(data, ArrayVar) else len(data)

        if not isinstance(columns, Var) and len(columns):
            if types.is_dataframe(type(data)) or (
                isinstance(data, Var) and types.is_dataframe(data._var_type)
            ):
                msg = "Cannot pass in both a pandas dataframe and columns to the data_editor component."
                raise ValueError(msg)
            props["columns"] = [
                format.format_data_editor_column(col) for col in columns
            ]

        if "theme" in props:
            theme = props.get("theme")
            if isinstance(theme, Mapping):
                props["theme"] = DataEditorTheme(**theme)

        # Allow by default to select a region of cells in the grid.
        props.setdefault("get_cells_for_selection", True)

        # Disable on_paste by default if not provided.
        props.setdefault("on_paste", False)

        if props.pop("get_cell_content", None) is not None:
            logger.warning(
                "get_cell_content is not user configurable, the provided value will be discarded"

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Drop the columns prop and let Reflex derive columns from the DataFrame
  2. Or pre-process the DataFrame: df = df[desired_cols].rename(...) and pass only data
  3. Or convert data to a plain list and pass columns explicitly

Example fix

# before
rx.data_editor(data=df, columns=["a", "b"])
# after
rx.data_editor(data=df[["a", "b"]])
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
if isinstance(data, pd.DataFrame) and columns:
    data = data[[c if isinstance(c, str) else c['name'] for c in columns]]
    columns = None
rx.data_editor(data=data, columns=columns)

Type guard

def is_dataframe_like(data: Any) -> bool:
    import pandas as pd
    return isinstance(data, pd.DataFrame) or (hasattr(data, '_var_type') and issubclass(getattr(data._var_type, '__mro_entries__', (type,)).__class__, type) and False)

Prevention

When it happens

Trigger: rx.data_editor(data=df, columns=[Column(name="x"), ...]) where df is a pandas DataFrame (or a Var typed as a DataFrame).

Common situations: Trying to rename/reorder columns by passing columns alongside a DataFrame instead of transforming the DataFrame itself.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/a8a868e03c5f6290. Report an issue: GitHub.