{"record":{"id":"236a28bb19178c9e","repo":"microsoft/qlib","slug":"please-implement-the-create-recorder-method","errorCode":null,"errorMessage":"Please implement the `create_recorder` method.","messagePattern":"Please implement the `create_recorder` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/exp.py","lineNumber":87,"sourceCode":"        recorder_status : str\r\n            the status the recorder to be set with when ending (SCHEDULED, RUNNING, FINISHED, FAILED).\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `end` method.\")\r\n\r\n    def create_recorder(self, recorder_name=None):\r\n        \"\"\"\r\n        Create a recorder for each experiment.\r\n\r\n        Parameters\r\n        ----------\r\n        recorder_name : str\r\n            the name of the recorder to be created.\r\n\r\n        Returns\r\n        -------\r\n        A recorder object.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `create_recorder` method.\")\r\n\r\n    def search_records(self, **kwargs):\r\n        \"\"\"\r\n        Get a pandas DataFrame of records that fit the search criteria of the experiment.\r\n        Inputs are the search criteria user want to apply.\r\n\r\n        Returns\r\n        -------\r\n        A pandas.DataFrame of records, where each metric, parameter, and tag\r\n        are expanded into their own columns named metrics.*, params.*, and tags.*\r\n        respectively. For records that don't have a particular metric, parameter, or tag, their\r\n        value will be (NumPy) Nan, None, or None respectively.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `search_records` method.\")\r\n\r\n    def delete_recorder(self, recorder_id):\r\n        \"\"\"\r\n        Create a recorder for each experiment.\r","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/exp.py#L69-L105","documentation":"Experiment.create_recorder is an abstract stub; it must return a Recorder object and is only implemented in subclasses like MLflowExperiment. The NotImplementedError means the running object is the base Experiment (or a subclass missing this method), so recorder creation cannot proceed.","triggerScenarios":"Calling exp.create_recorder('name') on a directly instantiated Experiment; a custom Experiment backend that implements get_recorder but not create_recorder; unit tests instantiating the base class to probe the API.","commonSituations":"Developing a custom tracking backend and missing the factory method; using get_recorder(create=True) with a partially implemented subclass, which internally relies on recorder creation.","solutions":["Rely on MLflowExperiment (default via qlib.init) which creates MLflowRecorder instances.","Implement create_recorder(self, recorder_name=None) in your subclass to construct and return your Recorder type.","If you only need retrieval, call _get_recorder/get_recorder with create=False instead of create_recorder."],"exampleFix":"# before\nrec = Experiment('1', 'e').create_recorder('r')  # NotImplementedError\n\n# after\nfrom qlib.workflow.exp import MLflowExperiment\nrec = MLflowExperiment('1', 'e', uri='file:./mlruns').create_recorder('r')","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.exp import Experiment\nassert exp.__class__.create_recorder is not Experiment.create_recorder","typeGuard":"def can_create_recorders(exp) -> bool:\n    from qlib.workflow.exp import Experiment\n    return exp.__class__.create_recorder is not Experiment.create_recorder","tryCatchPattern":null,"preventionTips":["Default to MLflowExperiment via qlib.init for recorder creation.","If you only need an existing recorder, call get_recorder(create=False)."],"tags":["qlib","abstract-method","not-implemented","recorder"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}