mlflow/mlflow · error · TypeError
Unsupported image object type: {type(image)}. `image` must b
Error message
Unsupported image object type: {type(image)}. `image` must be one of numpy.ndarray, PIL.Image.Image, and mlflow.Image. What it means
log_image() accepts images only as numpy.ndarray, PIL.Image.Image, or mlflow.Image (which is converted to PIL internally). Any other object (e.g. matplotlib Figure, file path string, torch Tensor) fails the isinstance checks and raises a TypeError naming the received type.
Source
Thrown at mlflow/tracking/client.py:3261
elif artifact_file is None and key is None:
raise TypeError(
"Invalid arguments: Please specify exactly one of `artifact_file` or `key`. Use "
"`key` to log dynamic image charts or `artifact_file` for saving static images. "
)
import numpy as np
# Convert image type to PIL if its a numpy array
if isinstance(image, np.ndarray):
image = convert_to_pil_image(image)
elif isinstance(image, Image):
image = image.to_pil()
else:
# Import PIL and check if the image is a PIL image
import PIL.Image
if not isinstance(image, PIL.Image.Image):
raise TypeError(
f"Unsupported image object type: {type(image)}. "
"`image` must be one of numpy.ndarray, "
"PIL.Image.Image, and mlflow.Image."
)
if artifact_file is not None:
with self._log_artifact_helper(run_id, artifact_file) as tmp_path:
image.save(tmp_path)
elif key is not None:
# Check image key for invalid characters
if not re.match(r"^[a-zA-Z0-9_\-./ ]+$", key):
raise ValueError(
"The `key` parameter may only contain alphanumerics, underscores (_), "
"dashes (-), periods (.), spaces ( ), and slashes (/)."
f"The provided key `{key}` contains invalid characters."
)
View on GitHub (pinned to 6a27f2decc)
Solutions
- Convert the object before logging: plt Figure -> fig.canvas buffer -> np.asarray, or save to a file and log with artifact_file.
- Convert tensors with np.asarray(tensor) or tensor.numpy() before passing.
- Wrap file paths yourself: Image.open(path) (PIL) then pass the PIL image.
- If using mlflow.Image, ensure the object is actually an mlflow.Image instance, not a similarly named class.
Example fix
// before
fig, ax = plt.subplots()
client.log_image(run_id, fig, artifact_file="plot.png") # Figure unsupported
// after
fig.savefig("plot.png")
from PIL import Image
client.log_image(run_id, Image.open("plot.png"), artifact_file="plot.png") Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
import PIL.Image
import mlflow
def is_loggable_image(image):
return isinstance(image, (np.ndarray, PIL.Image.Image, mlflow.Image)) Type guard
def is_loggable_image(image) -> bool:
import numpy as np, PIL.Image, mlflow
return isinstance(image, (np.ndarray, PIL.Image.Image, mlflow.Image)) Try / catch
try:
client.log_image(run_id, img, artifact_file="image.png")
except TypeError as e:
if "Unsupported image object type" in str(e):
img = np.asarray(img) # or Image.open(path) / img.to_pil()
client.log_image(run_id, img, artifact_file="image.png")
else:
raise Prevention
- Convert matplotlib Figures to arrays/PIL before logging
- Convert framework tensors with np.asarray or .numpy()
- Never pass file path strings; open them with PIL first
When it happens
Trigger: Passing a matplotlib.figure.Figure, a file path string, a torch/tensorflow tensor, an OpenCV image without converting, or any object that is not ndarray/PIL.Image/mlflow.Image to the `image` parameter.
Common situations: Plotting with matplotlib and passing the Figure directly instead of converting to an array; passing a local path string expecting the client to read it; framework tensors that were never converted with np.asarray or .numpy().
Related errors
- Unsupported data type.
- adapter_type must be a string, got {type(adapter_type).__nam
- Scorer returned an unexpected value type {type(result).__nam
- Scorer or Feedback returned an unexpected value type {type(v
- Expected data to be a dict, got {type(data).__name__}
AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29).
Data as JSON: /api/errors/1c45d54a0a762128.
Report an issue: GitHub.