sgl-project/sglang · error · ValueError
input image is empty
Error message
input image is empty
What it means
Raised by recenter in mesh3d_utils.py when the nonzero bounding box of a mask collapses to zero height or width (crop_h == 0 or crop_w == 0). Because coords = np.nonzero(mask) on a fully-empty mask yields min/max over empty arrays producing a degenerate box, the function cannot build a centered crop.
Source
Thrown at python/sglang/multimodal_gen/runtime/utils/mesh3d_utils.py:978
if image.shape[-1] == 4:
mask = image[..., 3]
else:
mask = np.ones_like(image[..., 0:1]) * 255
image = np.concatenate([image, mask], axis=-1)
mask = mask[..., 0]
height, width, channels = image.shape
size = max(height, width)
result = np.zeros((size, size, channels), dtype=np.uint8)
coords = np.nonzero(mask)
x_min, x_max = coords[0].min(), coords[0].max()
y_min, y_max = coords[1].min(), coords[1].max()
crop_h = x_max - x_min
crop_w = y_max - y_min
if crop_h == 0 or crop_w == 0:
raise ValueError("input image is empty")
desired_size = int(size * (1 - border_ratio))
scale = desired_size / max(crop_h, crop_w)
scaled_h = int(crop_h * scale)
scaled_w = int(crop_w * scale)
x2_min = (size - scaled_h) // 2
x2_max = x2_min + scaled_h
y2_min = (size - scaled_w) // 2
y2_max = y2_min + scaled_w
result[x2_min:x2_max, y2_min:y2_max] = cv2.resize(
image[x_min:x_max, y_min:y_max],
(scaled_w, scaled_h),
interpolation=cv2.INTER_AREA,
)
bg = np.ones((result.shape[0], result.shape[1], 3), dtype=np.uint8) * 255
View on GitHub (pinned to 0132848349)
Solutions
- Check mask.any() / mask.sum() > 0 before calling recenter
- Verify the mask isn't inverted or thresholded too hard — inspect unique values np.unique(mask)
- Confirm you're passing the correct mask array (right channel, right dtype, 0/255 vs 0/1 range)
- Re-run or swap the upstream segmentation/matting model if it produces empty masks
Example fix
// before
recenter(image, mask, size=512)
// after
if not mask.any():
raise ValueError("empty mask; skipping recenter")
recenter(image, mask, size=512) Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def mask_is_usable(mask: np.ndarray) -> bool:
m = np.asarray(mask)
nz = np.nonzero(m)
return nz[0].size > 1 and nz[1].size > 1 # non-degenerate bbox
if not mask_is_usable(mask):
raise ValueError("mask empty or degenerate; skip recenter") Try / catch
try:
recenter(image, mask, size=size)
except ValueError as e:
if "input image is empty" in str(e):
# fall back to plain resize without cropping
pass Prevention
- Sanitize masks (check .any() and bbox extent) before recenter
- Standardize mask value range (0/1 vs 0/255) at pipeline boundaries
- Test threshold values against a sample of real inputs
When it happens
Trigger: Calling load_image / recenter with an all-zero mask; masks where nonzero pixels form a single row or column after thresholding also trigger it (crop_h or crop_w becomes 0).
Common situations: Thresholding masks too aggressively (everything below threshold); matting/segmentation models returning empty masks for images with no detected subject; wrong mask channel or inverted mask passed in; grayscale images converted incorrectly so the mask is all background.
Related errors
- Image is fully transparent
- Position map {height}x{width} is not divisible by {grid_reso
- v_cache must be provided
- q can only be None when only_qv=True
- q must be provided unless qv is provided with only_qv=True
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/cccd9504aefe31b4.
Report an issue: GitHub.