mlflow/mlflow · error · ValueError

The number of objectives must be greater than 0.

Error message

The number of objectives must be greater than 0.

What it means

A multi-objective study must declare at least one direction. MlflowSparkStudy raises this ValueError when directions is provided as an empty sequence, because an empty objectives list cannot be optimized.

Source

Thrown at mlflow/pyspark/optuna/study.py:204

    def __init__(
        self,
        study_name: str,
        storage: MlflowStorage,
        sampler: samplers.BaseSampler | None = None,
        pruner: pruners.BasePruner | None = None,
        mlflow_tracking_uri: str | None = None,
        direction: str | StudyDirection | None = None,
        directions: Sequence[str | StudyDirection] | None = None,
    ):
        if direction is not None and directions is not None:
            raise ValueError("Specify only one of `direction` and `directions`.")
        if isinstance(directions, str):
            raise ValueError(
                "`directions` must be a sequence (e.g. list or tuple) of direction values, "
                "not a string. For single-objective optimization, use `direction=` instead."
            )
        if directions is not None and len(directions) == 0:
            raise ValueError("The number of objectives must be greater than 0.")
        self.study_name = study_name
        self._storage = storages.get_storage(storage)
        self.sampler = sampler or samplers.TPESampler()
        self.pruner = pruner if pruner is not None else pruners.MedianPruner()

        self.spark = SparkSession.active()

        # check whether the SparkConnect mode
        self._is_spark_connect_mode = is_spark_connect_mode()
        self._mlflow_tracking_env = mlflow_tracking_uri or mlflow.get_tracking_uri()
        mlflow.set_tracking_uri(self._mlflow_tracking_env)
        self.mlflow_client = MlflowClient()

        if not isinstance(self._storage, MlflowStorage):
            raise ValueError(
                f"MlflowSparkStudy only works with `MlflowStorage`. But get {type(self._storage)}."
            )

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Provide at least one direction, e.g. directions=["minimize"].
  2. Use direction= for a single objective.
  3. Validate the directions list length > 0 before constructing the study.
  4. Fix the config source that produced an empty list.

Example fix

# before
study = MlflowSparkStudy(directions=[])
# after
study = MlflowSparkStudy(direction=["minimize"][0] if n_obj == 1 else None, directions=["minimize"] if n_obj > 1 else None)
Defensive patterns

Strategy: validation

Validate before calling

if directions is not None and len(directions) == 0:
    raise ValueError("directions must contain at least one direction")

Try / catch

try:
    study = MlflowSparkStudy(directions=obj_dirs)
except ValueError as e:
    if "greater than 0" in str(e):
        obj_dirs = ["minimize"]
        study = MlflowSparkStudy(direction=obj_dirs[0])

Prevention

When it happens

Trigger: Calling MlflowSparkStudy(directions=[]) or passing an empty config list to directions.

Common situations: Building the directions list dynamically from config/CLI where defaults left it empty; an upstream filter removed all directions.

Related errors


AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29). Data as JSON: /api/errors/a3b91dae2b8df4d4. Report an issue: GitHub.