{"record":{"id":"7049e57a447e872d","repo":"microsoft/qlib","slug":"unsupported-policy-type-type-policy","errorCode":null,"errorMessage":"Unsupported policy type: {type(policy)}.","messagePattern":"Unsupported policy type: (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/rl/order_execution/strategy.py","lineNumber":500,"sourceCode":"                        \"obs_space\": self._state_interpreter.observation_space,\n                    }\n                )\n                network_inst = init_instance_by_config(network)\n            else:\n                network_inst = network\n\n            policy[\"kwargs\"].update(\n                {\n                    \"obs_space\": self._state_interpreter.observation_space,\n                    \"action_space\": self._action_interpreter.action_space,\n                    \"network\": network_inst,\n                }\n            )\n            self._policy = init_instance_by_config(policy)\n        elif isinstance(policy, BasePolicy):\n            self._policy = policy\n        else:\n            raise ValueError(f\"Unsupported policy type: {type(policy)}.\")\n\n        if self._policy is not None:\n            self._policy.eval()\n\n    def reset(self, outer_trade_decision: BaseTradeDecision | None = None, **kwargs: Any) -> None:\n        super().reset(outer_trade_decision=outer_trade_decision, **kwargs)\n\n    def _generate_trade_details(self, act: np.ndarray, exec_vols: List[float]) -> pd.DataFrame:\n        assert hasattr(self.outer_trade_decision, \"order_list\")\n\n        trade_details = []\n        for a, v, o in zip(act, exec_vols, getattr(self.outer_trade_decision, \"order_list\")):\n            trade_details.append(\n                {\n                    \"instrument\": o.stock_id,\n                    \"datetime\": self.trade_calendar.get_step_time()[0],\n                    \"freq\": self.trade_calendar.get_freq(),\n                    \"rl_exec_vol\": v,","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/rl/order_execution/strategy.py#L482-L518","documentation":"ValueError in `PWStrategy`-style RL strategy setup (qlib/rl/order_execution/strategy.py:500). The `policy` argument must be either a dict config (instantiated via `init_instance_by_config` after qlib injects obs_space/action_space/network) or a `BasePolicy` instance. Any other type — string, lambda, nn.Module, numpy array — is rejected.","triggerScenarios":"Passing `policy=\"ppo\"`, a bare torch module, or a partially constructed policy object to the RL executor strategy config; passing a list/tuple of configs; passing a tianshou policy that is not a qlib/tianshou `BasePolicy` subclass.","commonSituations":"YAML/JSON workflow configs where policy is given as a plain string class name instead of `{class: ..., module: ...}` dict; users trying to plug in a raw PyTorch net where a policy wrapper is required; version drift where the policy base class moved between tianshou releases.","solutions":["If using config-based init, pass a dict like `{\"class\": \"PPOPolicy\", \"module\": \"qlib.rl.order_execution.policy\"}` (kwargs obs_space/action_space/network are injected automatically).","If constructing manually, build a `BasePolicy` subclass instance first and pass that object.","Check `isinstance(policy, BasePolicy)` before strategy init in your own glue code to fail early with a clearer message."],"exampleFix":"// before\nstrategy = MyRLStrategy(policy=\"ppo\")  // string not supported\n// after\nstrategy = MyRLStrategy(policy={\"class\": \"PPOPolicy\", \"module\": \"qlib.rl.order_execution.policy\"})","handlingStrategy":"type-guard","validationCode":"from qlib.rl.utils.config import init_instance_by_config  # conceptually\nfrom qlib.model.base import Base as _QlibBase  # placeholder; use real BasePolicy import\nfrom tianshou.policy import BasePolicy\n\ndef check_policy(policy):\n    assert isinstance(policy, (dict, BasePolicy)), f\"policy must be dict config or BasePolicy, got {type(policy)}\"","typeGuard":"def is_supported_policy(p) -> bool:\n    from tianshou.policy import BasePolicy\n    return isinstance(p, (dict, BasePolicy)) and not isinstance(p, (str, list, tuple))","tryCatchPattern":"try:\n    strategy = MyRLStrategy(policy=policy_cfg)\nexcept ValueError as e:\n    if \"Unsupported policy type\" in str(e):\n        raise ValueError(\"wrap policy as dict config or BasePolicy instance\") from e\n    raise","preventionTips":["In YAML, always express policy as a dict with class/module keys.","Construct policy objects explicitly when you need custom nets, then pass the instance.","Validate the policy field in config loaders before starting long training runs."],"tags":["rl","strategy","config","policy","type-validation"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}