microsoft/qlib · error · FileNotFoundError

No file starting with '{filename_without_suffix}' found

Error message

No file starting with '{filename_without_suffix}' found

What it means

_find_pickle (qlib/rl/data/pickle_styled.py:78) resolves a pickle file for a given base name (without suffix) by probing '<name>.pkl' and '<name>.pkl.backtest'. If neither exists on disk it raises FileNotFoundError("No file starting with '<name>' found"). This typically surfaces via _read_pickle when qlib.rl loads process/order data for an exchange or date whose dump is absent.

Source

Thrown at qlib/rl/data/pickle_styled.py:78

            "$askV3",
            "$askV5",
        ]
    if shape == 6:
        return ["$high", "$low", "$open", "$close", "$vwap", "$volume"]
    elif shape == 5:
        return ["$high", "$low", "$open", "$close", "$volume"]
    raise ValueError(f"Unrecognized data shape: {shape}")


def _find_pickle(filename_without_suffix: Path) -> Path:
    suffix_list = [".pkl", ".pkl.backtest"]
    paths: List[Path] = []
    for suffix in suffix_list:
        path = filename_without_suffix.parent / (filename_without_suffix.name + suffix)
        if path.exists():
            paths.append(path)
    if not paths:
        raise FileNotFoundError(f"No file starting with '{filename_without_suffix}' found")
    if len(paths) > 1:
        raise ValueError(f"Multiple paths are found with prefix '{filename_without_suffix}': {paths}")
    return paths[0]


@lru_cache(maxsize=10)  # 10 * 40M = 400MB
def _read_pickle(filename_without_suffix: Path) -> pd.DataFrame:
    df = pd.read_pickle(_find_pickle(filename_without_suffix))
    index_cols = df.index.names

    df = df.reset_index()
    for date_col_name in ["date", "datetime"]:
        if date_col_name in df:
            df[date_col_name] = pd.to_datetime(df[date_col_name])
    df = df.set_index(index_cols)

    return df

View on GitHub (pinned to 79633dd950)

Solutions

  1. Check that <base>.pkl or <base>.pkl.backtest actually exists before constructing the data object
  2. Generate the missing dump with qlib's data dump/preprocessing scripts for RL
  3. Verify the data root directory and instrument/date path components in your config
  4. On case-sensitive filesystems, verify exact filename casing

Example fix

# before
data = pickle_styled.load(base_path)  # FileNotFoundError

# after
assert (base_path.with_suffix('.pkl')).exists() or base_path.with_name(base_path.name + '.pkl.backtest').exists(), f'dump missing: {base_path}'
data = pickle_styled.load(base_path)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
candidates = [base.with_name(base.name + s) for s in ('.pkl', '.pkl.backtest')]
assert any(p.is_file() for p in candidates), f'no pickle for {base}'

Try / catch

try:
    df = _read_pickle(base)
except FileNotFoundError as e:
    raise FileNotFoundError(f'run the RL data dump scripts first for {base}') from e

Prevention

When it happens

Trigger: Constructing pickle-styled data objects with a base path that has no .pkl or .pkl.backtest sibling; typo'd instrument/date directory names; referencing data dumps that were never downloaded or generated.

Common situations: Running RL backtests on data not yet dumped via the provided scripts; missing exchange-day pickles (holidays, delisted stocks); wrong data root path in config; case-sensitive filesystem mismatches.

Related errors


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