microsoft/qlib · error · ValueError
fields cannot be empty
Error message
fields cannot be empty
What it means
`Inst.get_column_names` requires at least one field. `D.features(...)` and the static data loaders build column names from the `fields` argument; an empty list means no data could ever be requested, so a ValueError is raised immediately.
Source
Thrown at qlib/data/data.py:538
instruments_d = Inst.list_instruments(instruments=instruments, freq=freq, as_list=False)
else:
# dict of instruments and timestamp
instruments_d = instruments
elif isinstance(instruments, (list, tuple, pd.Index, np.ndarray)):
# list or tuple of a group of instruments
instruments_d = list(instruments)
else:
raise ValueError("Unsupported input type for param `instrument`")
return instruments_d
@staticmethod
def get_column_names(fields):
"""
Get column names from input fields
"""
if len(fields) == 0:
raise ValueError("fields cannot be empty")
column_names = [str(f) for f in fields]
return column_names
@staticmethod
def parse_fields(fields):
# parse and check the input fields
return [ExpressionD.get_expression_instance(f) for f in fields]
@staticmethod
def dataset_processor(instruments_d, column_names, start_time, end_time, freq, inst_processors=[]):
"""
Load and process the data, return the data set.
- default using multi-kernel method.
"""
normalize_column_names = normalize_cache_fields(column_names)
# One process for one task, so that the memory will be freed quicker.
workers = max(min(C.get_kernels(freq), len(instruments_d)), 1)View on GitHub (pinned to 79633dd950)
Solutions
- Pass at least one valid expression, e.g. `fields=['$close']`.
- Debug why your field list is empty: print len(fields) before the call.
- If fields are generated, add an early assert/guard in your config code.
Example fix
# before df = D.features(insts, fields=[], start_time='2020-01-01', end_time='2020-12-31') # after df = D.features(insts, fields=['$close', '$volume'], start_time='2020-01-01', end_time='2020-12-31')
Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(fields, (list, tuple)) and len(fields) > 0, 'fields must be a non-empty list of expressions'
Type guard
def has_fields(fields) -> bool:
return bool(fields) and all(isinstance(f, str) for f in fields) Prevention
- Guard dynamically generated field lists with a len() check.
- Keep placeholder field lists in configs out of production.
When it happens
Trigger: Calling `D.features(instruments, fields=[])`, or building a DatasetH/DataHandler whose `data_loader` config has `fields: []`.
Common situations: Configs where fields are generated dynamically (e.g. alpha158 factors list comes back empty after a bug, or a YAML list is left as a placeholder). Also after renaming, when a fields-building helper returns [].
Related errors
- Invalid Qlib configuration (note: the global config has alre
- provider_uri cannot be None
- The size of fields must be greater than 0
- freq(={freq}) missing group(={_gp})
- Both default_exp_name and exp_name are None. OnlineToolR nee
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/73577a383b8f4210.
Report an issue: GitHub.