microsoft/qlib · error · ValueError
Unsupported input type for param `instrument`
Error message
Unsupported input type for param `instrument`
What it means
`Cal.calendar`-side sibling check in `Inst.get_instruments_d`: the `instruments` parameter of dataset/D.features calls must be either a dict (stockpool config if it has key 'market', else an {instrument: (start,end)} dict) or a list/tuple/pd.Index/np.ndarray. Any other type raises this ValueError before data loading starts.
Source
Thrown at qlib/data/data.py:528
@staticmethod
def get_instruments_d(instruments, freq):
"""
Parse different types of input instruments to output instruments_d
Wrong format of input instruments will lead to exception.
"""
if isinstance(instruments, dict):
if "market" in instruments:
# dict of stockpool config
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]
View on GitHub (pinned to 79633dd950)
Solutions
- Wrap the string: `D.features(instruments={'market': 'csi300'}, ...)` or `instruments=D.instruments('csi300')`.
- Convert sets: `instruments=list(my_set)`.
- For per-instrument time ranges, use `{'SH600000': ('2015-01-01', '2020-12-31')}`.
Example fix
# before
df = D.features('csi300', ['$close'], start_time='2020-01-01', end_time='2020-12-31')
# after
df = D.features({'market': 'csi300'}, ['$close'], start_time='2020-01-01', end_time='2020-12-31') Defensive patterns
Strategy: type-guard
Validate before calling
import pandas as pd, numpy as np
def normalize_instruments(inst):
if isinstance(inst, str):
return {'market': inst} # 'csi300' -> market config
if isinstance(inst, set):
return list(inst)
assert isinstance(inst, (dict, list, tuple, pd.Index, np.ndarray)), 'bad instruments type'
return inst Type guard
import pandas as pd, np
def is_supported_instruments(inst) -> bool:
return isinstance(inst, (dict, list, tuple, pd.Index, np.ndarray)) Prevention
- Normalize instruments through D.instruments()/list() at the config boundary.
- Never pass bare market strings or sets downstream.
When it happens
Trigger: Calling `D.features(instruments='csi300', ...)` or `DatasetH(instruments='all', ...)` with a bare string/None/int. Same shape rules as get_inst_type but a different error site.
Common situations: Passing market names as plain strings into DatasetH/D.features; passing a set of instruments (not accepted); passing None after a config-processing bug.
Related errors
- Unknown instrument type {inst}
- {freq} is not supported in NumpyQuote
- {method} is not supported
- Invalid Qlib configuration (note: the global config has alre
- provider_uri cannot be None
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/bf9719e3a5a5fe13.
Report an issue: GitHub.