unslothai/unsloth · error · ValueError
must be a multiple of 16
Error message
must be a multiple of 16
What it means
Raised by the width/height field_validator on DiffusionGenerateRequest when either dimension is not divisible by 16. Z-Image requires dimensions divisible by 16 (8x VAE downsample + 2x patch); non-multiples crash deep in the pipeline, so they are rejected up front with a clean 422.
Source
Thrown at studio/backend/models/inference.py:3072
seen.add(spec.id)
return value
@field_validator("reference_images")
@classmethod
def _bounded_reference_items(cls, value: Optional[list[str]]) -> Optional[list[str]]:
# Each reference is a base64 image; bound its length like init_image so several cannot buffer a multi-GB payload.
if value is not None:
for item in value:
if len(item) > 32 * 1024 * 1024:
raise ValueError("each reference image must be at most 32 MiB (base64)")
return value
@field_validator("width", "height")
@classmethod
def _multiple_of_16(cls, value: int) -> int:
# Z-Image requires dimensions divisible by 16 (8x VAE downsample + 2x patch); non-multiples crash deep in the pipeline.
if value % 16 != 0:
raise ValueError("must be a multiple of 16")
return value
@model_validator(mode = "after")
def _batch_seeds_json_safe(self) -> "DiffusionGenerateRequest":
# A batch derives seeds as seed..seed+batch_size-1, so a derived top-of-batch seed can exceed the 2**53-1 JSON-safe cap.
if self.seed is not None and self.seed + self.batch_size - 1 > 2**53 - 1:
raise ValueError(
"seed + batch_size - 1 must not exceed 2**53 - 1 so every per-image seed "
"stays JSON-safe (lower the seed or the batch_size)"
)
return self
class GalleryImage(BaseModel):
"""A persisted image's full generation recipe (embedded in the PNG too)."""
id: str = Field(..., description = "Stable id (the on-disk filename stem)")
url: str = Field(..., description = "Relative URL to fetch the PNG bytes")View on GitHub (pinned to 203007d190)
Solutions
- Round dimensions to the nearest multiple of 16 client-side (see validationCode).
- Set slider/input step to 16 in the UI.
- When computing from aspect ratio, quantize both dimensions after the ratio math.
Example fix
# before w, h = 1024, round(1024 * 1.5) # 1536 ok, but 1365 from other ratios fails # after def to_multiple_of_16(v): return max(256, min(2048, round(v / 16) * 16)) w, h = to_multiple_of_16(1024), to_multiple_of_16(1024 * 1.5)
Defensive patterns
Strategy: validation
Validate before calling
def quantize_dim(v: int) -> int:
return max(256, min(2048, round(v / 16) * 16)) Type guard
def is_valid_dimension(v: int) -> bool:
return 256 <= v <= 2048 and v % 16 == 0 Prevention
- Give dimension inputs/sliders step=16 within 256..2048
- Quantize after aspect-ratio math, not before
- Use multiples-of-16 presets as the only selectable sizes
When it happens
Trigger: POST /generate with width: 1000 or height: 1023 (the field bounds are 256..2048 but only multiples of 16 in that range are valid).
Common situations: UIs with free-form pixel inputs or sliders with step 1; deriving dimensions from aspect-ratio math (e.g. 1.5:1 of 1024 -> 1536 is fine but 1365 is not); client-side presets authored with off-by-a-few values.
Related errors
- duplicate LoRA id '{spec.id}'; list each adapter at most onc
- guidance_start must be <= guidance_end
- every prompt in prompts must be non-empty
- every seed must be between 0 and 2**53 - 1
- prompts and seeds must have the same length (got {len(self.p
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/61704869fe1d78d5.
Report an issue: GitHub.