microsoft/qlib · error · GymSpaceValidationError
Sample must be a tuple with same length as space.
Error message
Sample must be a tuple with same length as space.
What it means
Raised by qlib's space validator when a `gym.spaces.Tuple` space is validated against a sample that is not a tuple (after list/ndarray promotion) or has a different length than the space (qlib/rl/interpreter.py:122). Note the validator is lenient about types: list and np.ndarray are promoted to tuple; only genuine type/length mismatches fail.
Source
Thrown at qlib/rl/interpreter.py:122
Throw exception rather than returning true or false.
"""
if isinstance(space, spaces.Dict):
if not isinstance(x, dict) or len(x) != len(space):
raise GymSpaceValidationError("Sample must be a dict with same length as space.", space, x)
for k, subspace in space.spaces.items():
if k not in x:
raise GymSpaceValidationError(f"Key {k} not found in sample.", space, x)
try:
_gym_space_contains(subspace, x[k])
except GymSpaceValidationError as e:
raise GymSpaceValidationError(f"Subspace of key {k} validation error.", space, x) from e
elif isinstance(space, spaces.Tuple):
if isinstance(x, (list, np.ndarray)):
x = tuple(x) # Promote list and ndarray to tuple for contains check
if not isinstance(x, tuple) or len(x) != len(space):
raise GymSpaceValidationError("Sample must be a tuple with same length as space.", space, x)
for i, (subspace, part) in enumerate(zip(space, x)):
try:
_gym_space_contains(subspace, part)
except GymSpaceValidationError as e:
raise GymSpaceValidationError(f"Subspace of index {i} validation error.", space, x) from e
else:
if not space.contains(x):
raise GymSpaceValidationError("Validation error reported by gym.", space, x)
class GymSpaceValidationError(Exception):
def __init__(self, message: str, space: gym.Space, x: Any) -> None:
self.message = message
self.space = space
self.x = x
def __str__(self) -> str:View on GitHub (pinned to 79633dd950)
Solutions
- Check `len(space)` vs `len(sample)` from the exception's attached `space` and `x` attributes and make lengths equal.
- Ensure the interpreter returns a tuple (or list/ndarray) with one element per subspace, in the same order.
- Regenerate the Tuple space programmatically from the same config that builds the action so they can't drift.
Example fix
// before action_space = spaces.Tuple([spaces.Discrete(2), spaces.Discrete(2)]) act = (1,) # wrong length // after action_space = spaces.Tuple([spaces.Discrete(2), spaces.Discrete(2)]) act = (1, 0) # one element per subspace
Defensive patterns
Strategy: validation
Validate before calling
def validate_tuple_sample(space, x):
if isinstance(x, (list,)) : x = tuple(x)
assert isinstance(x, tuple), f"expected tuple, got {type(x)}"
assert len(x) == len(space), f"len {len(x)} != space len {len(space)}" Type guard
def matches_tuple_space(space: gym.Space, x: Any) -> bool:
if isinstance(space, gym.spaces.Tuple):
if isinstance(x, list):
x = tuple(x)
return isinstance(x, tuple) and len(x) == len(space)
return False Try / catch
try:
_gym_space_contains(action_space, converted_action)
except GymSpaceValidationError as e:
raise ValueError(f"Interpreter produced action not in action space: {e}") from e Prevention
- Build Tuple spaces with a comprehension over the same config that generates the action components.
- Return tuples (not scalars) from interpreters even for single-component actions.
- Validate converted actions inside ActionInterpreter during development.
When it happens
Trigger: Validating a `spaces.Tuple` space against e.g. an int, a dict, a string, or a list whose length differs from the number of subspaces. Typical in custom ActionInterpreter where the converted action must match a Tuple action space element-for-element.
Common situations: Changing the number of sub-actors/twins in an order-execution interpreter without updating the action space; passing a scalar where a 1-element tuple is expected; gym version upgrades changing Tuple internals.
Related errors
- Subspace of index {i} validation error.
- Key {k} not found in sample.
- Subspace of key {k} validation error.
- Validation error reported by gym.
- Sample must be a dict with same length as space.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/2ca2f42b98251794.
Report an issue: GitHub.