{"record":{"id":"c956b9a5467e2dc4","repo":"microsoft/qlib","slug":"please-implement-the-start-method","errorCode":null,"errorMessage":"Please implement the `start` method.","messagePattern":"Please implement the `start` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/exp.py","lineNumber":61,"sourceCode":"\r\n    def start(self, *, recorder_id=None, recorder_name=None, resume=False):\r\n        \"\"\"\r\n        Start the experiment and set it to be active. This method will also start a new recorder.\r\n\r\n        Parameters\r\n        ----------\r\n        recorder_id : str\r\n            the id of the recorder to be created.\r\n        recorder_name : str\r\n            the name of the recorder to be created.\r\n        resume : bool\r\n            whether to resume the first recorder\r\n\r\n        Returns\r\n        -------\r\n        An active recorder.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `start` method.\")\r\n\r\n    def end(self, recorder_status=Recorder.STATUS_S):\r\n        \"\"\"\r\n        End the experiment.\r\n\r\n        Parameters\r\n        ----------\r\n        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","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/exp.py#L43-L79","documentation":"qlib's Experiment is an abstract base class; start() only exists as a stub that raises NotImplementedError. The concrete implementation lives in MLflowExperiment (qlib/workflow/exp.py) and any user-defined subclass. Hitting this means the abstract Experiment.start() was called instead of an overridden implementation, i.e. the object is a bare/incomplete Experiment, not a configured tracking backend.","triggerScenarios":"Directly instantiating Experiment(...) and calling .start(); calling R.start_exp()/exp.start() when C['exp_manager']['class'] was changed to a class that inherits Experiment but never overrides start(); a custom experiment class whose method name is misspelled (e.g. Start or strat).","commonSituations":"Writing a custom tracking backend (e.g. wrapping TensorBoard/W&B instead of MLflow) and forgetting to implement start; copy-pasting an experiment class from an older qlib version whose abstract surface grew; class-resolver config pointing at the base class itself.","solutions":["Do not instantiate Experiment directly; use the default MLflowExperiment via qlib.init() (C.exp_manager['class'] defaults to 'MLflowExpManager').","If you subclass Experiment, implement start(self, recorder_id=None, recorder_name=None, resume=False) so it creates and activates a Recorder.","Check for typos/signature drift in your override; the method must be named exactly 'start' on the subclass.","Verify C['exp_manager']['class'] resolves to your fully implemented subclass before calling R.start_exp()."],"exampleFix":"# before\nexp = Experiment(id='1', name='e')\nexp.start()  # NotImplementedError\n\n# after\nfrom qlib.workflow.exp import MLflowExperiment\nexp = MLflowExperiment(id='1', name='e', uri='file:./mlruns')\nrec = exp.start()  # or implement start() in your own subclass","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.exp import Experiment, MLflowExperiment\nexp = R.get_exp()\nassert type(exp) is not Experiment, 'abstract Experiment in use; init qlib with MLflowExpManager'","typeGuard":"def is_concrete_experiment(exp) -> bool:\n    return type(exp).__name__ != 'Experiment' and exp.__class__.start is not Experiment.start","tryCatchPattern":null,"preventionTips":["Always obtain experiments via R.get_exp() after qlib.init() instead of constructing Experiment yourself.","When subclassing Experiment, run a smoke test that calls every abstract method once.","Keep C['exp_manager']['class'] set to a fully implemented class such as MLflowExpManager."],"tags":["qlib","abstract-method","not-implemented","experiment-tracking"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}