unslothai/unsloth · error · ValueError

every seed must be between 0 and 2**53 - 1

Error message

every seed must be between 0 and 2**53 - 1

What it means

Raised by the seeds field_validator on DiffusionGenerateRequest when any per-image seed is negative or exceeds 2**53-1. The bound matches the single-seed field so every per-image seed survives round-tripping through the gallery recipe, which stores recipes as JSON where integers beyond 2**53-1 lose precision.

Source

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

        max_length = 32,
        description = "Per-image seeds for batched generation: one image per seed (with "
        "`prompts`, lengths must match; alone, every image uses `prompt`). Each image is "
        "individually reproducible from its own seed.",
    )

    @field_validator("prompts")
    @classmethod
    def _non_empty_prompts(cls, value: Optional[list[str]]) -> Optional[list[str]]:
        if value is not None and any(not p.strip() for p in value):
            raise ValueError("every prompt in prompts must be non-empty")
        return value

    @field_validator("seeds")
    @classmethod
    def _seeds_json_safe(cls, value: Optional[list[int]]) -> Optional[list[int]]:
        # Same JSON safe-integer bound as `seed`, so every per-image seed survives the gallery recipe.
        if value is not None and any(s < 0 or s > 2**53 - 1 for s in value):
            raise ValueError("every seed must be between 0 and 2**53 - 1")
        return value

    @model_validator(mode = "after")
    def _prompts_seeds_lengths_match(self) -> "DiffusionGenerateRequest":
        if (
            self.prompts is not None
            and self.seeds is not None
            and len(self.prompts) != len(self.seeds)
        ):
            raise ValueError(
                f"prompts and seeds must have the same length (got {len(self.prompts)} "
                f"prompts, {len(self.seeds)} seeds)"
            )
        return self

    # Image-conditioned workflows (base64 or data-URL): init_image alone runs img2img, init_image + mask_image runs inpaint.
    # Cap each base64 string so one request cannot buffer a multi-GB payload; ~32 MiB fits a full 4096px image.
    init_image: Optional[str] = Field(

View on GitHub (pinned to 203007d190)

Solutions

  1. Generate seeds in [0, 2**53-1], e.g. random.randrange(2**53) in Python.
  2. Mask incoming 64-bit seeds: seed & ((1 << 53) - 1).
  3. Take abs() of computed seeds and reject the result if it still exceeds the cap.

Example fix

# before
seeds = [secrets.randbits(64) for _ in prompts]  # exceeds 2**53-1

# after
seeds = [random.randrange(2 ** 53) for _ in prompts]
Defensive patterns

Strategy: validation

Validate before calling

MAX_SEED = 2 ** 53 - 1
def valid_seeds(seeds: list[int] | None) -> bool:
    return seeds is None or all(0 <= s <= MAX_SEED for s in seeds)

Prevention

When it happens

Trigger: Sending seeds: [-1, 42] or seeds: [2**53] with a generation request; typically from generating 64-bit random seeds client-side instead of 53-bit.

Common situations: Using secrets.randbits(64) or UUID-derived integers for seeds; porting torch seed ranges; negative seeds from signed arithmetic on unsigned values.

Related errors


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