unslothai/unsloth · error · ValueError

each reference image must be at most 32 MiB (base64)

Error message

each reference image must be at most 32 MiB (base64)

What it means

Raised by the reference_images field_validator on DiffusionGenerateRequest when any single base64 reference image string exceeds 32 MiB. The cap (mirroring init_image's max_length) stops one request from buffering a multi-GB payload in memory.

Source

Thrown at studio/backend/models/inference.py:3064

        # Both apply paths suffix colliding adapter names, so a repeated id would load the SAME adapter twice and stack its effect past the weight bound.
        if value:
            seen: set[str] = set()
            for spec in value:
                if spec.id in seen:
                    raise ValueError(
                        f"duplicate LoRA id '{spec.id}'; list each adapter at most once"
                    )
                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)"
            )

View on GitHub (pinned to 203007d190)

Solutions

  1. Downscale and re-encode references to JPEG/WebP before base64 (see validationCode).
  2. Target <= 2048px on the short edge — beyond that the reference pipeline rescales anyway.
  3. Check len(b64) <= 32*1024*1024 per item before submitting batches.

Example fix

# before
b64 = base64.b64encode(open('raw_photo.png', 'rb').read()).decode()

# after
from PIL import Image
import io, base64
img = Image.open('raw_photo.png')
img.thumbnail((2048, 2048))
buf = io.BytesIO(); img.save(buf, 'JPEG', quality=90)
b64 = base64.b64encode(buf.getvalue()).decode()
Defensive patterns

Strategy: validation

Validate before calling

MAX_B64 = 32 * 1024 * 1024
def references_within_limit(refs: list[str] | None) -> bool:
    return refs is None or all(len(r) <= MAX_B64 for r in refs)

Prevention

When it happens

Trigger: Sending reference_images entries larger than 32*1024*1024 base64 characters — roughly a >24 MB raw image (base64 adds ~33% overhead), e.g. an uncompressed 8000x8000 PNG.

Common situations: Phone/procamera photos at full resolution; TIFF/BMP sources base64'd without re-encoding; a list of references where each passes a smaller per-item mental budget but one outlier dominates.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/c3bb9206888bdecb. Report an issue: GitHub.