unslothai/unsloth · error · ValueError

width and height must be sent together, or both omitted

Error message

width and height must be sent together, or both omitted

What it means

Raised by the _keyframe_canvas_needs_both_axes model_validator on VideoGenerateRequest. For KEYFRAME requests only (first_frame or last_frame set), the width/height canvas must be either fully specified or fully omitted, because the backend's _resolve_keyframes silently matches the source aspect ratio whenever either axis is missing — a half-specified canvas would be accepted but drawn differently than requested. The validator deliberately returns early for non-keyframe requests, since other model families (LTX, Wan, Hunyuan) and prompt-only H3 calls have always allowed a single axis to be resolved from family defaults.

Source

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

                "keyframes and references cannot be combined: MiniMax-H3 runs them against "
                "different denoiser partitions"
            )
        return self

    @model_validator(mode = "after")
    def _keyframe_canvas_needs_both_axes(self) -> "VideoGenerateRequest":
        # Omit both axes for "match source", or provide both for an explicit canvas.
        # KEYFRAME requests only. There a half-specified canvas is silently discarded:
        # _resolve_keyframes matches the source aspect whenever either axis is missing, so the
        # axis that was sent never reaches the render and the API would accept one recipe and
        # draw another. Without a keyframe the backend deliberately resolves the missing axis
        # from the family's default preset -- validate_video_request_shape and generate() both
        # document and implement that -- so applying the rule to every request would reject
        # half-specified LTX, Wan, Hunyuan and prompt-only H3 calls that have always been valid.
        if not (self.first_frame or self.last_frame):
            return self
        if (self.width is None) != (self.height is None):
            raise ValueError("width and height must be sent together, or both omitted")
        return self


class GalleryVideo(BaseModel):
    """A persisted clip's full generation recipe (the JSON sidecar of the MP4)."""

    id: str = Field(..., description = "Stable id (the on-disk filename stem)")
    url: str = Field(..., description = "Relative URL to fetch the MP4 bytes")
    prompt: str = Field(..., description = "Prompt used")
    negative_prompt: Optional[str] = Field(None, description = "Negative prompt, if any")
    width: int = Field(..., description = "Frame width")
    height: int = Field(..., description = "Frame height")
    num_frames: int = Field(..., description = "Number of frames")
    fps: int = Field(..., description = "Playback frame rate")
    duration_s: float = Field(..., description = "Clip duration in seconds")
    steps: int = Field(..., description = "Denoising steps")
    guidance: float = Field(..., description = "Guidance scale")
    guidance_2: Optional[float] = Field(

View on GitHub (pinned to 203007d190)

Solutions

  1. Send both width and height together for keyframe requests (compute the missing axis from the keyframe image's aspect ratio).
  2. Or send neither axis and let the backend match the source aspect ratio of the keyframe.
  3. Check your request builder for conditionally-set axis fields and make them all-or-nothing when first_frame/last_frame is present.

Example fix

# before
req = {"prompt": p, "first_frame": b64, "width": 1280}  # height missing
# after (explicit canvas)
req = {"prompt": p, "first_frame": b64, "width": 1280, "height": 720}
# after (match source aspect)
req = {"prompt": p, "first_frame": b64}
Defensive patterns

Strategy: validation

Validate before calling

def canvas_pairwise(req: dict) -> bool:
    if not (req.get("first_frame") or req.get("last_frame")):
        return True
    return (req.get("width") is None) == (req.get("height") is None)

Type guard

function canvasOk(req: { first_frame?: unknown; last_frame?: unknown; width?: number | null; height?: number | null }): boolean {
  if (!(req.first_frame || req.last_frame)) return true;
  return (req.width == null) === (req.height == null);
}

Prevention

When it happens

Trigger: POST to video generation with first_frame or last_frame set and exactly one of width/height provided, e.g. {"first_frame": b64, "width": 1280} with height omitted, or {"last_frame": b64, "height": 720} with width omitted.

Common situations: A UI where width comes from one input and height from a possibly-unset second input; code that computes height from an aspect ratio and passes it only when the math succeeds; copying a non-keyframe request template (where one axis is fine) and adding a keyframe to it.

Related errors


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