{"record":{"id":"d8683341a2b70fb7","repo":"microsoft/qlib","slug":"please-implement-the-get-recorder-method","errorCode":null,"errorMessage":"Please implement the `_get_recorder` method","messagePattern":"Please implement the `_get_recorder` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/exp.py","lineNumber":216,"sourceCode":"        Get specific recorder by name or id. If it does not exist, raise ValueError\r\n\r\n        Parameters\r\n        ----------\r\n        recorder_id :\r\n            The id of recorder\r\n        recorder_name :\r\n            The name of recorder\r\n\r\n        Returns\r\n        -------\r\n        Recorder:\r\n            The searched recorder\r\n\r\n        Raises\r\n        ------\r\n        ValueError\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `_get_recorder` method\")\r\n\r\n    RT_D = \"dict\"  # return type dict\r\n    RT_L = \"list\"  # return type list\r\n\r\n    def list_recorders(\r\n        self, rtype: Literal[\"dict\", \"list\"] = RT_D, **flt_kwargs\r\n    ) -> Union[List[Recorder], Dict[str, Recorder]]:\r\n        \"\"\"\r\n        List all the existing recorders of this experiment. Please first get the experiment instance before calling this method.\r\n        If user want to use the method `R.list_recorders()`, please refer to the related API document in `QlibRecorder`.\r\n\r\n        flt_kwargs : dict\r\n            filter recorders by conditions\r\n            e.g.  list_recorders(status=Recorder.STATUS_FI)\r\n\r\n        Returns\r\n        -------\r\n        The return type depends on `rtype`\r","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/exp.py#L198-L234","documentation":"_get_recorder is the protected lookup primitive of qlib's Experiment base class: given a recorder_id/recorder_name it must return the matching Recorder or raise ValueError. The base implementation is a stub, so this NotImplementedError means no concrete lookup backend (e.g. MLflowExperiment._get_recorder, which calls MlflowClient.get_run) is in place.","triggerScenarios":"get_recorder(...) on a base/incomplete Experiment, which internally calls self._get_recorder; direct exp._get_recorder(...) calls in custom code; a subclass overriding get_recorder but not the private _get_recorder.","commonSituations":"Implementing a custom tracking backend and missing the private lookup method even though the public get_recorder exists; test harnesses exercising the abstract interface.","solutions":["Use MLflowExperiment (via qlib.init defaults) whose _get_recorder resolves runs through MLflow.","In a custom subclass, implement _get_recorder(self, recorder_id=None, recorder_name=None) returning your Recorder or raising ValueError when not found.","Prefer the public get_recorder API and ensure your subclass fully implements the private hooks it relies on."],"exampleFix":"# before\nclass MyExp(Experiment):\n    ...\nexp.get_recorder(recorder_id='abc')  # base _get_recorder -> NotImplementedError\n\n# after\nclass MyExp(Experiment):\n    def _get_recorder(self, recorder_id=None, recorder_name=None):\n        run = self._client.get_run(recorder_id) if recorder_id else self._find_by_name(recorder_name)\n        if run is None:\n            raise ValueError('No valid recorder has been found')\n        return MyRecorder(self.id, self._uri, mlflow_run=run)","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.exp import Experiment\nassert exp.__class__._get_recorder is not Experiment._get_recorder, 'record lookup not implemented'","typeGuard":"def has_recorder_lookup(exp) -> bool:\n    from qlib.workflow.exp import Experiment\n    return exp.__class__._get_recorder is not Experiment._get_recorder","tryCatchPattern":null,"preventionTips":["Use the public get_recorder API; it surfaces clear ValueError messages from concrete backends.","Custom backends must implement the private hooks, not just public wrappers."],"tags":["qlib","abstract-method","not-implemented","recorder","protected-api"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}