microsoft/qlib · error · ValueError

Both default_exp_name and exp_name are None. OnlineToolR nee

Error message

Both default_exp_name and exp_name are None. OnlineToolR needs a specific experiment.

What it means

OnlineToolR._get_exp_name raises ValueError when both the exp_name argument and the tool's default_exp_name (set in OnlineToolR.__init__) are None. OnlineToolR operates on the recorders of one specific MLflow experiment, so with no experiment name it has nothing to query; the error is a fail-fast guard rather than a silent empty result.

Source

Thrown at qlib/workflow/online/utils.py:183

            exp_name (str): the experiment name. If None, then use default_exp_name.
        """
        exp_name = self._get_exp_name(exp_name)
        online_models = self.online_models(exp_name=exp_name)
        for rec in online_models:
            try:
                updater = PredUpdater(rec, to_date=to_date, from_date=from_date)
            except LoadObjectError as e:
                # skip the recorder without pred
                self.logger.warn(f"An exception `{str(e)}` happened when load `pred.pkl`, skip it.")
                continue
            updater.update()

        self.logger.info(f"Finished updating {len(online_models)} online model predictions of {exp_name}.")

    def _get_exp_name(self, exp_name):
        if exp_name is None:
            if self.default_exp_name is None:
                raise ValueError(
                    "Both default_exp_name and exp_name are None. OnlineToolR needs a specific experiment."
                )
            exp_name = self.default_exp_name
        return exp_name

View on GitHub (pinned to 79633dd950)

Solutions

  1. Pass the experiment name at construction: OnlineToolR(default_exp_name='my_experiment')
  2. Or pass exp_name explicitly to the method call that raised (e.g. tool.online_models(exp_name='my_experiment') where supported)
  3. Verify the name matches an existing experiment via R.list_experiments() so the next call does not fail with error 540

Example fix

# before
tool = OnlineToolR()
tool.online_models()  # ValueError: both names None

# after
tool = OnlineToolR(default_exp_name='my_experiment')
tool.online_models()
Defensive patterns

Strategy: validation

Validate before calling

from qlib.workflow.online.utils import OnlineToolR

def make_tool(exp_name: str):
    if exp_name is None:
        raise ValueError('exp_name is required for OnlineToolR')
    return OnlineToolR(default_exp_name=exp_name)

Try / catch

try:
    tool.online_models()
except ValueError as e:
    if 'Both default_exp_name and exp_name are None' in str(e):
        tool.default_exp_name = 'my_experiment'  # then retry once
    else:
        raise

Prevention

When it happens

Trigger: Constructing OnlineToolR() without default_exp_name and then calling any method that resolves the experiment (online_models, update_online_pred, reset_online_tag) without an explicit exp_name; passing exp_name=None explicitly to those methods on a default-less tool; creating RollingStrategy/OnlineManager with a tool that was never given an experiment name.

Common situations: Copy-pasting example code that omitted the constructor argument; assuming the tool inherits the experiment from the surrounding Qlib workflow context (it does not); refactoring code and dropping the default_exp_name parameter.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/04b5ad869f2300c8. Report an issue: GitHub.