microsoft/qlib · error · ValueError
cannot assign data as `num_states==0`
Error message
cannot assign data as `num_states==0`
What it means
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.
Source
Thrown at qlib/contrib/data/dataset.py:244
obj._memory = self._memory
obj._zeros = self._zeros
# update index for this batch
date_index = self._index.get_level_values(1)
obj._batch_slices = self._batch_slices[(date_index >= start_date) & (date_index <= end_date)]
mask = (self._daily_index.values >= start_date) & (self._daily_index.values <= end_date)
obj._daily_slices = self._daily_slices[mask]
obj._daily_index = self._daily_index[mask]
return obj
def restore_index(self, index):
return self._index[index]
def restore_daily_index(self, daily_index):
return pd.Index(self._daily_index.loc[daily_index])
def assign_data(self, index, vals):
if self.num_states == 0:
raise ValueError("cannot assign data as `num_states==0`")
if isinstance(vals, torch.Tensor):
vals = vals.detach().cpu().numpy()
self._memory[index] = vals
def clear_memory(self):
if self.num_states == 0:
raise ValueError("cannot clear memory as `num_states==0`")
self._memory[:] = 0
def train(self):
"""enable traning mode"""
self.batch_size, self.n_samples, self.drop_last, self.shuffle = self.params
def eval(self):
"""enable evaluation mode"""
self.batch_size = -1
self.n_samples = None
self.drop_last = FalseView on GitHub (pinned to 79633dd950)
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.
Example fix
# before ds = RLDataSet(data, seq_len=20, num_states=0) ds.assign_data(idx, states) # -> ValueError # after ds = RLDataSet(data, seq_len=20, num_states=states.shape[1]) ds.assign_data(idx, states)
Defensive patterns
Strategy: validation
Validate before calling
if ds.num_states == 0:
raise ValueError('dataset built with num_states=0 cannot store state data; rebuild with num_states>0')
ds.assign_data(index, vals) Type guard
def can_assign_state(ds) -> bool:
return getattr(ds, 'num_states', 0) > 0 Try / catch
try:
ds.assign_data(idx, vals)
except ValueError as e:
if 'num_states==0' in str(e):
pass # memoryless dataset: nothing to store
else:
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- cannot clear memory as `num_states==0`
- invalid memory_mode `{self.memory_mode}`
- This type of input is not supported
- Must specify the path to save the dataset.
- Empty data from dataset, please check your dataset config.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/91505d8ecf0e15d3.
Report an issue: GitHub.