mlflow/mlflow · error · MlflowException

BAD_REQUEST

BAD_REQUEST

Error message

Model libraries are already added

What it means

WheeledModel.save_model packages a model's dependencies as pip wheels into the model directory. If the MLmodel file already records a wheels section, the wheels were previously added and adding them again would overwrite/corrupt the package, so MLflow rejects the request with BAD_REQUEST.

Source

Thrown at mlflow/models/wheeled_model.py:117

            mlflow_model: The new :py:mod:`mlflow.models.Model` metadata file to store the
                updated model metadata.
        """
        from mlflow.pyfunc import ENV, FLAVOR_NAME, _extract_conda_env

        path = os.path.abspath(path)
        _validate_and_prepare_target_save_path(path)

        local_model_path = _download_artifact_from_uri(self._model_uri, output_path=path)

        wheels_dir = os.path.join(local_model_path, _WHEELS_FOLDER_NAME)
        pip_requirements_path = os.path.join(local_model_path, _REQUIREMENTS_FILE_NAME)
        model_metadata_path = os.path.join(local_model_path, MLMODEL_FILE_NAME)

        model_metadata = Model.load(model_metadata_path)

        # Check if the model file has `wheels` set to True
        if model_metadata.__dict__.get(_WHEELS_FOLDER_NAME, None) is not None:
            raise MlflowException("Model libraries are already added", BAD_REQUEST)

        conda_env = _extract_conda_env(model_metadata.flavors.get(FLAVOR_NAME, {}).get(ENV, None))
        conda_env_path = os.path.join(local_model_path, conda_env)
        if conda_env is None and not os.path.isfile(pip_requirements_path):
            raise MlflowException(
                "Cannot add libraries for model with no logged dependencies.", BAD_REQUEST
            )

        if not os.path.isfile(pip_requirements_path):
            self._create_pip_requirement(conda_env_path, pip_requirements_path)

        WheeledModel._download_wheels(
            pip_requirements_path=pip_requirements_path, dst_path=wheels_dir
        )

        # Keep a copy of the original requirement.txt
        shutil.copy2(pip_requirements_path, os.path.join(local_model_path, _ORIGINAL_REQ_FILE_NAME))

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Do not call add_libraries again on a model that already has wheels; use the existing wheeled model
  2. Log/save a fresh copy of the original (non-wheeled) model and call add_libraries on that copy
  3. If you must re-add, delete the wheels entry and the wheels directory from the model copy first

Example fix

// before
model_info = mlflow.sklearn.log_model(model, "model")
wheeled = WheeledModel(model_uri=model_info.model_uri)
wheeled.add_libraries().log(...)  # second run raises
def add_wheels():
    wheeled.add_libraries()
add_wheels()
add_wheels()

// after
def add_wheels():
    mi = mlflow.sklearn.log_model(model, "model")  # fresh copy each run
    WheeledModel(model_uri=mi.model_uri).add_libraries()
Defensive patterns

Strategy: validation

Validate before calling

import mlflow
from mlflow.models import Model
from mlflow.models.model import MLMODEL_FILE_NAME
import os
def has_wheels(model_dir: str) -> bool:
    meta = Model.load(os.path.join(model_dir, MLMODEL_FILE_NAME))
    return meta.__dict__.get("wheels") is not None

Try / catch

from mlflow.exceptions import MlflowException
try:
    wheeled.add_libraries()
except MlflowException as e:
    if "already added" in str(e):
        print("Model already wheeled; reusing existing package")
    else:
        raise

Prevention

When it happens

Trigger: Calling WheeledModel(...).save_model() or .log() on a model directory whose MLmodel file already contains a wheels key (i.e., add_libraries was already applied to this model).

Common situations: Re-running a script that calls add_libraries on the same logged model; chaining add_libraries calls twice; re-deploying code that modifies an already-wheeled model copy.

Understand the failure class

Background: BAD_REQUEST error code: request rejected as invalid (HTTP 400) - causes and fixes across libraries — this error's family across 8 libraries.

Related errors


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