microsoft/qlib · error · TypeError
stock selector must be type str|list, or slice(None), rather
Error message
stock selector must be type str|list, or slice(None), rather than {stock_selector} What it means
Raised by the storage selector parser (qlib/data/dataset/storage.py) after extracting the stock selector: the final value must be a str, a list, or slice(None). Any other type (int, dict, None, numpy array, tuple, pd.Index) fails this check with a TypeError. It is the last line of defense normalizing instrument selectors before they are used to filter the hash_df of instruments.
Source
Thrown at qlib/data/dataset/storage.py:154
if isinstance(selector, tuple) and self.stock_level < len(selector):
# full selector format
stock_selector = selector[self.stock_level]
time_selector = selector[1 - self.stock_level]
elif isinstance(selector, (list, str)) and self.stock_level == 0:
# only stock selector
stock_selector = selector
elif level in ("instrument", self.stock_level):
if isinstance(selector, tuple):
# NOTE: How could the stock level selector be a tuple?
stock_selector = selector[0]
raise TypeError(
"I forget why would this case appear. But I think it does not make sense. So we raise a error for that case."
)
elif isinstance(selector, (list, str)):
stock_selector = selector
if not isinstance(stock_selector, (list, str)) and stock_selector != slice(None):
raise TypeError(f"stock selector must be type str|list, or slice(None), rather than {stock_selector}")
if stock_selector == slice(None):
return self.hash_df, time_selector
if isinstance(stock_selector, str):
stock_selector = [stock_selector]
select_dict = dict()
for each_stock in sorted(stock_selector):
if each_stock in self.hash_df:
select_dict[each_stock] = self.hash_df[each_stock]
return select_dict, time_selector
def fetch(
self,
selector: Union[pd.Timestamp, slice, str, pd.Index] = slice(None, None),
level: Union[str, int] = "datetime",
col_set: Union[str, List[str]] = DataHandler.CS_ALL,View on GitHub (pinned to 79633dd950)
Solutions
- Convert the selector to a list of instrument-code strings: selector = list(pd_index) or selector = arr.tolist().
- Wrap a single code in a string or list: "SH600000" or ["SH600000"], never a one-element tuple.
- Use slice(None) explicitly when you want all instruments.
- Check that the selector variable is actually set (not None) before calling the API.
Example fix
# before storage.select(np.array(["SH600000", "SZ000001"]), level="instrument") # after codes = np.array(["SH600000", "SZ000001"]).tolist() storage.select(codes, level="instrument")
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(selector, (str, list)) and selector != slice(None):
selector = list(selector) # accept pd.Index / np.array / iterable Type guard
def is_stock_selector(s) -> bool:
return isinstance(s, (str, list)) or s == slice(None) Try / catch
try:
storage.select(selector, level="instrument")
except TypeError as e:
if "stock selector" in str(e):
storage.select(list(selector), level="instrument")
else:
raise Prevention
- Normalize pd.Index/np.array/tuple to plain list before any storage call.
- Never pass None; default to slice(None) when 'all instruments' is meant.
When it happens
Trigger: Calling the instrument-level selection API with selector=0, selector=None, selector=np.array([...]), selector=('SH600000',), or a dict. Also triggered when a selector variable is unset and defaults to None.
Common situations: Programmatically building selectors and passing a pandas Index or numpy array instead of converting to list; forwarding an unprocessed user argument into low-level storage APIs; None leaking in from a missing config value.
Related errors
- I forget why would this case appear. But I think it does not
- type(i) = {type(i)}
- This type of `limit_threshold` is not supported
- stock data from resam_ts_data must be a number, pd.Series or
- provider_uri does not support {type(provider_uri)}
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/5e341d9f13d7d107.
Report an issue: GitHub.