{"record":{"id":"590c9ad2d534ded2","repo":"microsoft/qlib","slug":"please-implement-the-set-online-tag-method","errorCode":null,"errorMessage":"Please implement the `set_online_tag` method.","messagePattern":"Please implement the `set_online_tag` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/online/utils.py","lineNumber":42,"sourceCode":"    ONLINE_KEY = \"online_status\"  # the online status key in recorder\n    ONLINE_TAG = \"online\"  # the 'online' model\n    OFFLINE_TAG = \"offline\"  # the 'offline' model, not for online serving\n\n    def __init__(self):\n        \"\"\"\n        Init OnlineTool.\n        \"\"\"\n        self.logger = get_module_logger(self.__class__.__name__)\n\n    def set_online_tag(self, tag, recorder: Union[list, object]):\n        \"\"\"\n        Set `tag` to the model to sign whether online.\n\n        Args:\n            tag (str): the tags in `ONLINE_TAG`, `OFFLINE_TAG`\n            recorder (Union[list,object]): the model's recorder\n        \"\"\"\n        raise NotImplementedError(f\"Please implement the `set_online_tag` method.\")\n\n    def get_online_tag(self, recorder: object) -> str:\n        \"\"\"\n        Given a model recorder and return its online tag.\n\n        Args:\n            recorder (Object): the model's recorder\n\n        Returns:\n            str: the online tag\n        \"\"\"\n        raise NotImplementedError(f\"Please implement the `get_online_tag` method.\")\n\n    def reset_online_tag(self, recorder: Union[list, object]):\n        \"\"\"\n        Offline all models and set the recorders to 'online'.\n\n        Args:","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/online/utils.py#L24-L60","documentation":"OnlineTool.set_online_tag is an abstract method of the OnlineTool base class (qlib/workflow/online/utils.py). The base raises NotImplementedError to force concrete tools to define how a tag (ONLINE_TAG / OFFLINE_TAG) is written onto one or more recorders. Hitting it means your code called set_online_tag on the base class or on a subclass that did not override it.","triggerScenarios":"Instantiating raw OnlineTool() and calling set_online_tag(tag, recorder); subclassing OnlineTool (e.g. for a custom backend) without implementing set_online_tag; a strategy constructed with a custom tool whose tag methods were forgotten, so reset_online_tag / prepare flows crash here.","commonSituations":"Writing a custom OnlineTool for a non-recorder storage backend; copying OnlineToolR and stripping methods; using OnlineTool base directly instead of OnlineToolR.","solutions":["Use the built-in OnlineToolR (recorder-based implementation) instead of the abstract OnlineTool: OnlineToolR(default_exp_name='...')","If you subclass OnlineTool, implement set_online_tag(self, tag, recorder) handling both a single recorder and a list","Verify you are not accidentally instantiating the base class in your strategy's __init__ (OnlineStrategy defaults self.tool = OnlineTool())"],"exampleFix":"# before\ntool = OnlineTool()              # abstract\ntool.set_online_tag('online', rec)  # NotImplementedError\n\n# after\ntool = OnlineToolR(default_exp_name='my_experiment')\ntool.set_online_tag('online', rec)","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.online.utils import OnlineTool, OnlineToolR\n\ndef make_tool(exp_name=None):\n    # never hand out the abstract OnlineTool\n    return OnlineToolR(default_exp_name=exp_name)","typeGuard":"from qlib.workflow.online.utils import OnlineTool\n\ndef is_concrete_tool(tool) -> bool:\n    return type(tool).set_online_tag is not OnlineTool.set_online_tag","tryCatchPattern":"try:\n    tool.set_online_tag('online', rec)\nexcept NotImplementedError as e:\n    raise TypeError(f'{type(tool).__name__} is not a usable OnlineTool: {e}') from e","preventionTips":["Always construct OnlineToolR (or your full subclass), never OnlineTool","When overriding OnlineStrategy, pass a concrete tool instead of relying on its default OnlineTool()","In OnlineTool subclasses, implement all five hooks: set_online_tag, get_online_tag, reset_online_tag, online_models, update_online_pred"],"tags":["qlib","online-tool","abstract-method","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}