{"record":{"id":"4e48033b065df9c8","repo":"microsoft/qlib","slug":"seed-iterator-for-training-is-not-available","errorCode":null,"errorMessage":"Seed iterator for training is not available.","messagePattern":"Seed iterator for training is not available\\.","errorType":"exception","errorClass":"SeedIteratorNotAvailable","httpStatus":null,"severity":"error","filePath":"qlib/rl/trainer/vessel.py","lineNumber":56,"sourceCode":"    The ship also defines the most important logic of the core training part,\n    and (optionally) some callbacks to insert customized logics at specific events.\n    \"\"\"\n\n    simulator_fn: Callable[[InitialStateType], Simulator[InitialStateType, StateType, ActType]]\n    state_interpreter: StateInterpreter[StateType, ObsType]\n    action_interpreter: ActionInterpreter[StateType, PolicyActType, ActType]\n    policy: BasePolicy\n    reward: Reward\n    trainer: Trainer\n\n    def assign_trainer(self, trainer: Trainer) -> None:\n        self.trainer = weakref.proxy(trainer)  # type: ignore\n\n    def train_seed_iterator(self) -> ContextManager[Iterable[InitialStateType]] | Iterable[InitialStateType]:\n        \"\"\"Override this to create a seed iterator for training.\n        If the iterable is a context manager, the whole training will be invoked in the with-block,\n        and the iterator will be automatically closed after the training is done.\"\"\"\n        raise SeedIteratorNotAvailable(\"Seed iterator for training is not available.\")\n\n    def val_seed_iterator(self) -> ContextManager[Iterable[InitialStateType]] | Iterable[InitialStateType]:\n        \"\"\"Override this to create a seed iterator for validation.\"\"\"\n        raise SeedIteratorNotAvailable(\"Seed iterator for validation is not available.\")\n\n    def test_seed_iterator(self) -> ContextManager[Iterable[InitialStateType]] | Iterable[InitialStateType]:\n        \"\"\"Override this to create a seed iterator for testing.\"\"\"\n        raise SeedIteratorNotAvailable(\"Seed iterator for testing is not available.\")\n\n    def train(self, vector_env: BaseVectorEnv) -> Dict[str, Any]:\n        \"\"\"Implement this to train one iteration. In RL, one iteration usually refers to one collect.\"\"\"\n        raise NotImplementedError()\n\n    def validate(self, vector_env: FiniteVectorEnv) -> Dict[str, Any]:\n        \"\"\"Implement this to validate the policy once.\"\"\"\n        raise NotImplementedError()\n\n    def test(self, vector_env: FiniteVectorEnv) -> Dict[str, Any]:","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/rl/trainer/vessel.py#L38-L74","documentation":"SeedIteratorNotAvailable raised by the default `Vessel.train_seed_iterator` (qlib/rl/trainer/vessel.py:56). A vessel is abstract: subclasses must override the seed-iterator hooks so the trainer knows which simulator initial states to train on. Calling the base implementation signals the override is missing.","triggerScenarios":"Implementing a custom `Vessel` subclass that provides `train`/`validate`/`test` but not `train_seed_iterator`; passing a vessel instance whose seed methods were left at defaults into `Trainer.fit(train_vessel, ...)`.","commonSituations":"Adapting the RL workflow to a new task and copying only the train loop; refactor renaming the method so the override is lost; using the vessel in a context where training is not intended (then use a vessel that explicitly raises or skip fit).","solutions":["Override `train_seed_iterator` in your vessel to return an iterable of initial states (e.g. a generator over order/date combinations), optionally a context-manager iterable for resource lifecycle.","Model it on `OrderExecutionVessel` / existing vessels in the codebase that yield seeds from an order list.","If training is genuinely unsupported for this vessel, catch `SeedIteratorNotAvailable` at the call site and skip the fit phase with a clear log."],"exampleFix":"// before\nclass MyVessel(Vessel):\n    def train(self, venv): ...\n    # train_seed_iterator missing -> SeedIteratorNotAvailable\n// after\nclass MyVessel(Vessel):\n    def train_seed_iterator(self):\n        return iter(self.order_list)  # iterable of initial states\n    def train(self, venv): ...","handlingStrategy":"validation","validationCode":"from qlib.rl.trainer.vessel import Vessel\n\ndef train_seeds_available(vessel: Vessel) -> bool:\n    return type(vessel).train_seed_iterator is not Vessel.train_seed_iterator","typeGuard":"def is_trainable_vessel(v) -> bool:\n    from qlib.rl.trainer.vessel import Vessel\n    return (\n        type(v).train_seed_iterator is not Vessel.train_seed_iterator\n        and type(v).train is not Vessel.train\n    )","tryCatchPattern":"from qlib.rl.trainer.vessel import SeedIteratorNotAvailable\ntry:\n    seeds = vessel.train_seed_iterator()\nexcept SeedIteratorNotAvailable:\n    raise RuntimeError(\"override train_seed_iterator before calling Trainer.fit\") from None","preventionTips":["Treat vessel seed hooks as required abstract methods when adapting to a new task.","Copy the seed-iterator trio (train/val/test) from an existing vessel first.","Fail fast in vessel __init__ if seed sources (e.g. order lists) are empty."],"tags":["rl","trainer","vessel","not-implemented","subclassing"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}