{"record":{"id":"97edcaec472e4fb2","repo":"microsoft/qlib","slug":"please-implement-the-start-run-method","errorCode":null,"errorMessage":"Please implement the `start_run` method.","messagePattern":"Please implement the `start_run` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/recorder.py","lineNumber":114,"sourceCode":"        name : str\r\n            name of the file to be loaded.\r\n\r\n        Returns\r\n        -------\r\n        The saved object.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `load_object` method.\")\r\n\r\n    def start_run(self):\r\n        \"\"\"\r\n        Start running or resuming the Recorder. The return value can be used as a context manager within a `with` block;\r\n        otherwise, you must call end_run() to terminate the current run. (See `ActiveRun` class in mlflow)\r\n\r\n        Returns\r\n        -------\r\n        An active running object (e.g. mlflow.ActiveRun object).\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `start_run` method.\")\r\n\r\n    def end_run(self):\r\n        \"\"\"\r\n        End an active Recorder.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `end_run` method.\")\r\n\r\n    def log_params(self, **kwargs):\r\n        \"\"\"\r\n        Log a batch of params for the current run.\r\n\r\n        Parameters\r\n        ----------\r\n        keyword arguments\r\n            key, value pair to be logged as parameters.\r\n        \"\"\"\r\n        raise NotImplementedError(f\"Please implement the `log_params` method.\")\r\n\r","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/recorder.py#L96-L132","documentation":"Recorder.start_run is the abstract method that begins (or resumes) a tracking run and returns an active-run context manager (mlflow.ActiveRun for the MLflow backend). The base class raises NotImplementedError; the error means start_run was called on the abstract Recorder — the MLflowRecorder override was not in play because the instance is the base class or an incomplete custom subclass.","triggerScenarios":"Directly instantiating qlib.workflow.recorder.Recorder and calling start_run; a custom Recorder subclass registered with QlibRecorder that lacks start_run; the workflow trying to use the default (abstract) recorder because no concrete recorder was created for the tracking URI scheme.","commonSituations":"Extending qlib with a non-MLflow tracker; misconfiguring QlibRecorder so it keeps the abstract default; calling low-level recorder APIs while bypassing R.start.","solutions":["Drive runs through QlibRecorder/R.start(experiment_name=...), which creates and starts an MLflowRecorder for you","Implement start_run(self) in a custom Recorder subclass, returning a context-manager active-run object, and also implement end_run and the other abstract methods","Verify which recorder class you actually hold: type(recorder) should be MLflowRecorder (or your subclass), never the bare Recorder"],"exampleFix":"# before\nrec = Recorder(...)\nwith rec.start_run():   # NotImplementedError\n    ...\n\n# after\nfrom qlib.workflow import R\nwith R.start(experiment_name='my_exp'):\n    rec = R.get_recorder()\n    ...","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.recorder import Recorder\n\ndef assert_startable(rec):\n    if type(rec).start_run is Recorder.start_run:\n        raise TypeError(f'{type(rec).__name__} does not implement start_run')","typeGuard":"from qlib.workflow.recorder import Recorder\n\ndef can_start_run(rec) -> bool:\n    return type(rec).start_run is not Recorder.start_run","tryCatchPattern":"try:\n    with rec.start_run():\n        ...\nexcept NotImplementedError as e:\n    raise TypeError('use R.start(...) which drives a concrete MLflowRecorder') from e","preventionTips":["Start runs with R.start(experiment_name=...); it handles recorder creation and start_run","Do not bypass QlibRecorder to poke low-level recorder lifecycle methods","Register custom recorder subclasses only after implementing the full abstract surface"],"tags":["qlib","recorder","abstract-method","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}