{"record":{"id":"91505d8ecf0e15d3","repo":"microsoft/qlib","slug":"cannot-assign-data-as-num-states-0","errorCode":null,"errorMessage":"cannot assign data as `num_states==0`","messagePattern":"cannot assign data as `num_states==0`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/data/dataset.py","lineNumber":244,"sourceCode":"        obj._memory = self._memory\n        obj._zeros = self._zeros\n        # update index for this batch\n        date_index = self._index.get_level_values(1)\n        obj._batch_slices = self._batch_slices[(date_index >= start_date) & (date_index <= end_date)]\n        mask = (self._daily_index.values >= start_date) & (self._daily_index.values <= end_date)\n        obj._daily_slices = self._daily_slices[mask]\n        obj._daily_index = self._daily_index[mask]\n        return obj\n\n    def restore_index(self, index):\n        return self._index[index]\n\n    def restore_daily_index(self, daily_index):\n        return pd.Index(self._daily_index.loc[daily_index])\n\n    def assign_data(self, index, vals):\n        if self.num_states == 0:\n            raise ValueError(\"cannot assign data as `num_states==0`\")\n        if isinstance(vals, torch.Tensor):\n            vals = vals.detach().cpu().numpy()\n        self._memory[index] = vals\n\n    def clear_memory(self):\n        if self.num_states == 0:\n            raise ValueError(\"cannot clear memory as `num_states==0`\")\n        self._memory[:] = 0\n\n    def train(self):\n        \"\"\"enable traning mode\"\"\"\n        self.batch_size, self.n_samples, self.drop_last, self.shuffle = self.params\n\n    def eval(self):\n        \"\"\"enable evaluation mode\"\"\"\n        self.batch_size = -1\n        self.n_samples = None\n        self.drop_last = False","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/data/dataset.py#L226-L262","documentation":"assign_data on the RL dataset writes into the internal state-memory tensor, which only exists when the dataset was created with num_states > 0. With num_states == 0 the memory array has zero width and cannot store anything, so qlib raises ValueError instead of silently dropping data or corrupting shapes.","triggerScenarios":"Building the dataset with num_states=0 (pure supervised mode) but then calling assign_data(index, vals) — typically from an RL training loop that stores state/action data each batch.","commonSituations":"Reusing a generic RL training script against a dataset configured for supervised learning; refactoring where num_states is read from config and defaults to 0 while the training loop still calls assign_data.","solutions":["Construct the dataset with num_states > 0 equal to your state dimension if you intend to call assign_data.","Or guard the training loop: skip assign_data/clear_memory when dataset.num_states == 0.","Check that the num_states value survives your config merge — a missing key defaulting to 0 is the usual root cause."],"exampleFix":"# before\nds = RLDataSet(data, seq_len=20, num_states=0)\nds.assign_data(idx, states)  # -> ValueError\n# after\nds = RLDataSet(data, seq_len=20, num_states=states.shape[1])\nds.assign_data(idx, states)","handlingStrategy":"validation","validationCode":"if ds.num_states == 0:\n    raise ValueError('dataset built with num_states=0 cannot store state data; rebuild with num_states>0')\nds.assign_data(index, vals)","typeGuard":"def can_assign_state(ds) -> bool:\n    return getattr(ds, 'num_states', 0) > 0","tryCatchPattern":"try:\n    ds.assign_data(idx, vals)\nexcept ValueError as e:\n    if 'num_states==0' in str(e):\n        pass  # memoryless dataset: nothing to store\n    else:\n        raise","preventionTips":["Construct the RL dataset with num_states matching your environment's state dimension.","Guard all memory-write calls in the training loop with num_states > 0 checks."],"tags":["qlib","reinforcement-learning","dataset","state-validation"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}