microsoft/qlib · error · ValueError

freq(={freq}) missing group(={_gp})

Error message

freq(={freq}) missing group(={_gp})

What it means

Raised by StaticDataLoader-style grouped loaders (qlib/data/dataset/loader.py) when the dataset config declares multiple groups (is_group=True) and the freq parameter is a dict, but a group name present in config has no matching key in the freq dict. The loader needs a frequency per group to load each group's dataframe, so a missing entry makes the config incomplete. It is a config-validation error thrown at loader construction, before any data is read.

Source

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

        """
        self.filter_pipe = filter_pipe
        self.swap_level = swap_level
        self.freq = freq

        # sample
        self.inst_processors = inst_processors if inst_processors is not None else {}
        assert isinstance(
            self.inst_processors, (dict, list)
        ), f"inst_processors(={self.inst_processors}) must be dict or list"

        super().__init__(config)

        if self.is_group:
            # check sample config
            if isinstance(freq, dict):
                for _gp in config.keys():
                    if _gp not in freq:
                        raise ValueError(f"freq(={freq}) missing group(={_gp})")
                assert (
                    self.inst_processors
                ), f"freq(={self.freq}), inst_processors(={self.inst_processors}) cannot be None/empty"

    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:
        if instruments is None:
            warnings.warn("`instruments` is not set, will load all stocks")
            instruments = "all"
        if isinstance(instruments, str):
            instruments = D.instruments(instruments, filter_pipe=self.filter_pipe)

View on GitHub (pinned to 79633dd950)

Solutions

  1. Add the missing group key to the freq dict, e.g. freq = {'group1': 'day', 'group2': 'day'} so every key of config is covered.
  2. Check for exact group-name mismatches (case, whitespace) between config.keys() and freq.keys(); print both dicts to compare.
  3. If you did not intend grouped loading, remove the groups from the dataset/handler config so is_group is False.
  4. When freq is a dict, also supply a non-empty inst_processors mapping (e.g. inst_processors={'group1': [...], ...}) or the following assert will fail.

Example fix

# before
config = {"price": {"kwargs": {...}}, "factor": {"kwargs": {...}}}
freq = {"price": "day"}
loader = NestedGroupStaticDataLoader(config=..., freq=freq)

# after
freq = {"price": "day", "factor": "day"}  # every config group has a freq entry
Defensive patterns

Strategy: validation

Validate before calling

missing = set(config.keys()) - set(freq.keys())
if isinstance(freq, dict) and missing:
    raise ConfigError(f"freq dict is missing groups: {missing}")

Try / catch

try:
    loader = GroupedLoader(config=config, freq=freq, inst_processors=procs)
except ValueError as e:
    if "missing group" in str(e):
        # rebuild freq dict covering config.keys() and retry once
        freq = {g: freq.get(g, default_freq) for g in config}
        loader = GroupedLoader(config=config, freq=freq, inst_processors=procs)
    else:
        raise

Prevention

When it happens

Trigger: Calling a grouped data loader (e.g. MultiDataLoader / DataHandlerLP with groups) with config = {'group1': {...}, 'group2': {...}} but freq = {'group1': 'day'} — 'group2' is in config.keys() but not in freq. Also occurs when a group is added to the handler config without updating the matching freq mapping.

Common situations: Setting up grouped datasets in qlib workflows (e.g. Alpha158 + Alpha360 groups, or train/valid groups) where handlers and processors are configured per group; typos or case mismatches between group names in config and freq; adding a new group in an experiment notebook and forgetting the freq entry. Note that when freq is a dict, inst_processors must also be non-empty (a separate assert follows).

Related errors


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