microsoft/qlib · error · NotImplementedError

This type of input is not supported

Error message

This type of input is not supported

What it means

Raised by get_level_index (qlib/data/dataset/utils.py) when its level argument is neither a str nor an int. The function resolves a level name to its integer position in a DataFrame's MultiIndex (falling back to the conventional ('datetime','instrument') names); only strings and integers are meaningful inputs, so anything else raises NotImplementedError.

Source

Thrown at qlib/data/dataset/utils.py:38

        data
    level : Union[str, int]
        index level

    Returns
    -------
    int:
        The level index in the multiple index
    """
    if isinstance(level, str):
        try:
            return df.index.names.index(level)
        except (AttributeError, ValueError):
            # NOTE: If level index is not given in the data, the default level index will be ('datetime', 'instrument')
            return ("datetime", "instrument").index(level)
    elif isinstance(level, int):
        return level
    else:
        raise NotImplementedError(f"This type of input is not supported")


def fetch_df_by_index(
    df: pd.DataFrame,
    selector: Union[pd.Timestamp, slice, str, list, pd.Index],
    level: Union[str, int],
    fetch_orig=True,
) -> pd.DataFrame:
    """
    fetch data from `data` with `selector` and `level`

    selector are assumed to be well processed.
    `fetch_df_by_index` is only responsible for get the right level

    Parameters
    ----------
    selector : Union[pd.Timestamp, slice, str, list]
        selector

View on GitHub (pinned to 79633dd950)

Solutions

  1. Pass the level as a plain str (e.g. "datetime" or "instrument") or a plain int (e.g. 0 or 1).
  2. Ensure the level variable is not None: give it an explicit default in your calling code.
  3. If the value may be a numpy integer, coerce with int(level) before calling.

Example fix

# before
level = None  # fell through from caller
idx = get_level_index(df, level)

# after
idx = get_level_index(df, level="datetime")  # or level=0
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(level, (str, int)) or level is None:
    raise TypeError("level must be str or int")

Type guard

def is_valid_level(lv) -> bool:
    return isinstance(lv, (str, int)) and not isinstance(lv, bool) and lv is not None

Prevention

When it happens

Trigger: get_level_index(df, level=None), level=1.0 (float), level=slice(None), or a variable holding an unexpected object. Often hit indirectly through fetch_df_by_index or dataset code that forwards an unvalidated level value.

Common situations: A level parameter defaults to None in caller code and is passed through without setting it; passing a numpy integer (np.int64) usually works because isinstance(np.int64(...), int) can be False on some platforms/versions — if so, cast to plain int; refactoring code and losing the level argument.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/166752326e777e0c. Report an issue: GitHub.