microsoft/qlib · error · NotImplementedError

This type of input is not supported

Error message

This type of input is not supported

What it means

Inside a valid list/tuple fields config, `_parse_fields_info` inspects the first element to decide the shape: a str means 'list of expressions used as both exprs and names'; a list/tuple means a (exprs, names) pair. A first element of any other type (int, dict, None, nested further) raises NotImplementedError.

Source

Thrown at qlib/data/dataset/loader.py:107

        if self.is_group:
            self.fields = {grp: self._parse_fields_info(fields_info) for grp, fields_info in config.items()}
        else:
            self.fields = self._parse_fields_info(config)

    def _parse_fields_info(self, fields_info: Union[list, tuple]) -> Tuple[list, list]:
        if len(fields_info) == 0:
            raise ValueError("The size of fields must be greater than 0")

        if not isinstance(fields_info, (list, tuple)):
            raise TypeError("Unsupported type")

        if isinstance(fields_info[0], str):
            exprs = names = fields_info
        elif isinstance(fields_info[0], (list, tuple)):
            exprs, names = fields_info
        else:
            raise NotImplementedError(f"This type of input is not supported")
        return exprs, names

    @abc.abstractmethod
    def load_group_df(
        self,
        instruments,
        exprs: list,
        names: list,
        start_time: Union[str, pd.Timestamp] = None,
        end_time: Union[str, pd.Timestamp] = None,
        gp_name: str = None,
    ) -> pd.DataFrame:
        """
        load the dataframe for specific group

        Parameters
        ----------
        instruments :

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use the flat form: fields=['$close', '$open'].
  2. Or exactly one nesting level for names: fields=(['$close', '$open'], ['close', 'open']).
  3. Print repr(fields[0]) and ensure it is a str or a list/tuple.

Example fix

# before
fields = [[['Ref($close, -1)'], ['label']]]

# after
fields = (['Ref($close, -1)'], ['label'])
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_fields_shape(cfg) -> bool:
    if isinstance(cfg, dict):
        return all(valid_fields_shape(v) for v in cfg.values())
    if not isinstance(cfg, (list, tuple)) or len(cfg) == 0:
        return False
    head = cfg[0]
    return isinstance(head, str) or (isinstance(head, (list, tuple)) and len(cfg) == 2)

Type guard

def is_valid_fields_info(f) -> bool:
    if not isinstance(f, (list, tuple)) or not f:
        return False
    h = f[0]
    return isinstance(h, str) or (isinstance(h, (list, tuple)) and len(f) == 2)

Prevention

When it happens

Trigger: Passing fields=[[ ['$close'], ['close'] ]] (over-nested), fields=[{'expr': '$close'}] (dicts), or fields=[0, 1]. Also passing (['$close'], ['close'], 'extra') — first element fine, but a 3-tuple unpack fails elsewhere; the direct trigger is a non-str non-list first element.

Common situations: Building (exprs, names) pairs programmatically and wrapping once too many times; mixing per-group dict configs into the fields list.

Related errors


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