{"record":{"id":"5e341d9f13d7d107","repo":"microsoft/qlib","slug":"stock-selector-must-be-type-str-list-or-slice-non","errorCode":null,"errorMessage":"stock selector must be type str|list, or slice(None), rather than {stock_selector}","messagePattern":"stock selector must be type str\\|list, or slice\\(None\\), rather than (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"qlib/data/dataset/storage.py","lineNumber":154,"sourceCode":"            if isinstance(selector, tuple) and self.stock_level < len(selector):\n                # full selector format\n                stock_selector = selector[self.stock_level]\n                time_selector = selector[1 - self.stock_level]\n            elif isinstance(selector, (list, str)) and self.stock_level == 0:\n                # only stock selector\n                stock_selector = selector\n        elif level in (\"instrument\", self.stock_level):\n            if isinstance(selector, tuple):\n                # NOTE: How could the stock level selector be a tuple?\n                stock_selector = selector[0]\n                raise TypeError(\n                    \"I forget why would this case appear. But I think it does not make sense. So we raise a error for that case.\"\n                )\n            elif isinstance(selector, (list, str)):\n                stock_selector = selector\n\n        if not isinstance(stock_selector, (list, str)) and stock_selector != slice(None):\n            raise TypeError(f\"stock selector must be type str|list, or slice(None), rather than {stock_selector}\")\n\n        if stock_selector == slice(None):\n            return self.hash_df, time_selector\n\n        if isinstance(stock_selector, str):\n            stock_selector = [stock_selector]\n\n        select_dict = dict()\n        for each_stock in sorted(stock_selector):\n            if each_stock in self.hash_df:\n                select_dict[each_stock] = self.hash_df[each_stock]\n        return select_dict, time_selector\n\n    def fetch(\n        self,\n        selector: Union[pd.Timestamp, slice, str, pd.Index] = slice(None, None),\n        level: Union[str, int] = \"datetime\",\n        col_set: Union[str, List[str]] = DataHandler.CS_ALL,","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/data/dataset/storage.py#L136-L172","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nstorage.select(np.array([\"SH600000\", \"SZ000001\"]), level=\"instrument\")\n\n# after\ncodes = np.array([\"SH600000\", \"SZ000001\"]).tolist()\nstorage.select(codes, level=\"instrument\")","handlingStrategy":"type-guard","validationCode":"if not isinstance(selector, (str, list)) and selector != slice(None):\n    selector = list(selector)  # accept pd.Index / np.array / iterable","typeGuard":"def is_stock_selector(s) -> bool:\n    return isinstance(s, (str, list)) or s == slice(None)","tryCatchPattern":"try:\n    storage.select(selector, level=\"instrument\")\nexcept TypeError as e:\n    if \"stock selector\" in str(e):\n        storage.select(list(selector), level=\"instrument\")\n    else:\n        raise","preventionTips":["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."],"tags":["qlib","storage","selector","type-error"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}