mlflow/mlflow · error · MlflowException

Invalid artifact path: '{artifact_path}'. {bad_path_message(

Error message

Invalid artifact path: '{artifact_path}'. {bad_path_message(artifact_path)}

What it means

verify_artifact_path rejects artifact paths that are not unique/safe (path_not_unique check, e.g. paths containing traversal or non-unique segments). It raises a generic MlflowException with a message describing why the path is invalid. Called before log_artifact and _get_or_create_artifact_dir.

Source

Thrown at mlflow/store/artifact/artifact_repo.py:814

        chunks: AsyncIterable[bytes],
        artifact_file_name: str,
        artifact_path: str | None = None,
    ) -> None:
        """
        Log artifact contents from an async chunk stream.

        Args:
            chunks: Async iterable yielding binary chunks containing the artifact contents.
            artifact_file_name: Artifact filename to log. Any directory components are
                ignored; use ``artifact_path`` to specify the destination directory.
            artifact_path: Directory within the run's artifact directory in which to log
                the artifact.
        """


def verify_artifact_path(artifact_path):
    if artifact_path and path_not_unique(artifact_path):
        raise MlflowException(
            f"Invalid artifact path: '{artifact_path}'. {bad_path_message(artifact_path)}"
        )


# Attachment IDs are auto-generated as UUID4 by Attachment.__init__.
# Strict UUID validation doubles as path traversal prevention.
def _validate_attachment_path(path: str) -> None:
    try:
        parsed = uuid.UUID(path)
        if str(parsed) != path:
            raise ValueError("Non-canonical UUID format")
    except (ValueError, AttributeError, TypeError):
        # error_code is INVALID_PARAMETER_VALUE but this is an attribute/type validation failure
        raise MlflowException(
            f"Invalid attachment path: '{path}'. Attachment path must be a valid UUID.",
            error_code=INVALID_PARAMETER_VALUE,
            error_class="ATTRIBUTE_NOT_FOUND",
        )

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Sanitize the artifact_path: remove '..' and normalize with os.path.normpath / PurePosixPath
  2. Use flat, single-level, alphanumeric artifact paths (e.g. 'models/checkpoint-1')
  3. Read the bad_path_message portion of the error for the exact rule violated

Example fix

// before
client.log_artifact(run_id, "model.pkl", artifact_path="../../etc/evil")  # MlflowException
// after
artifact_path = "models/checkpoint-1"
assert artifact_path == os.path.normpath(artifact_path)
client.log_artifact(run_id, "model.pkl", artifact_path=artifact_path)
Defensive patterns

Strategy: validation

Validate before calling

from mlflow.utils.validation import path_not_unique
def safe_artifact_path(p):
    if p and path_not_unique(p):
        raise ValueError(p)
    return p

Try / catch

try:
    client.log_artifact(run_id, local, artifact_path=p)
except MlflowException as e:
    if 'Invalid artifact path' in str(e):
        p = os.path.normpath(p).strip('/')
        client.log_artifact(run_id, local, artifact_path=p)

Prevention

When it happens

Trigger: Calling log_artifact / log_artifacts with an artifact_path such as '../escape', paths with repeated redundant segments, or other forms flagged by path_not_unique; also invoked internally when creating the artifact dir.

Common situations: Building artifact paths from untrusted or unsanitized user input; joining paths with '..' segments; double slashes or ambiguous relative segments in experiment/run artifact subpaths.

Related errors


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