unslothai/unsloth · error · ValueError
keyframes and references cannot be combined: MiniMax-H3 runs
Error message
keyframes and references cannot be combined: MiniMax-H3 runs them against different denoiser partitions
What it means
Raised by the same model_validator on VideoGenerateRequest (MiniMax-H3). MiniMax-H3 runs first_frame/last_frame keyframes and free-form reference media (reference_images/videos/audios) against different denoiser partitions, so the two conditioning modes are mutually exclusive in one request. The check fires when any reference list is non-empty AND either first_frame or last_frame is set. It is the third check in the validator, after the budget and standalone-audio checks.
Source
Thrown at studio/backend/models/inference.py:3793
if len(item) > 32 * 1024 * 1024:
raise ValueError("each reference must be at most 32 MiB (base64)")
return value
@model_validator(mode = "after")
def _references_fit_the_models_budget(self) -> "VideoGenerateRequest":
images = self.reference_images or []
videos = self.reference_videos or []
audios = self.reference_audios or []
total = len(images) + len(videos) + len(audios)
if total > 12:
raise ValueError(f"MiniMax-H3 takes at most 12 references in total, got {total}")
# Standalone audio must accompany an image or video reference.
if audios and not images and not videos:
raise ValueError(
"reference audio needs at least one reference image or video to go with"
)
if (images or videos or audios) and (self.first_frame or self.last_frame):
raise ValueError(
"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):View on GitHub (pinned to 203007d190)
Solutions
- Decide the conditioning mode: either keep first_frame/last_frame and drop all reference_* fields, or keep references and drop the keyframes.
- If you need both a start anchor and extra references, fold the anchor image into reference_images and remove first_frame.
- Audit request-building code for stale keyframe fields left over from a previous model's template.
Example fix
# before
req = {
"prompt": p,
"first_frame": start_b64,
"reference_images": [style_b64],
}
# after (mode 1: keyframes only)
req = {"prompt": p, "first_frame": start_b64}
# after (mode 2: references only)
req = {"prompt": p, "reference_images": [start_b64, style_b64]} Defensive patterns
Strategy: validation
Validate before calling
def keyframes_xor_references(req: dict) -> bool:
has_refs = any(req.get(k) for k in ("reference_images", "reference_videos", "reference_audios"))
has_kf = bool(req.get("first_frame") or req.get("last_frame"))
return not (has_refs and has_kf) Type guard
function conditioningExclusive(req: Record<string, unknown>): boolean {
const refs = ['reference_images','reference_videos','reference_audios'].some(k => Array.isArray(req[k]) && (req[k] as unknown[]).length > 0);
const kf = Boolean(req.first_frame || req.last_frame);
return !(refs && kf);
} Try / catch
try { await client.generate(req) } catch (e) { if (/cannot be combined/.test(String(e))) { delete req.first_frame; delete req.last_frame; return client.generate(req); } throw e; } Prevention
- Make the UI a mode switch: keyframes OR references, never both visible
- Strip keyframe fields when a request template is reused for reference-based generation
When it happens
Trigger: POST to the video generation endpoint with e.g. {"first_frame": "...", "reference_images": ["..."]}, or {"last_frame": "...", "reference_audios": ["..."], "reference_videos": ["..."]} — any non-empty reference list combined with either keyframe field.
Common situations: Migrating from another model family (LTX, Wan, Hunyuan) that permits mixing keyframes with references; a UI that shows keyframe and reference widgets simultaneously and submits both; incrementally adding reference images to an existing keyframe workflow without clearing first_frame/last_frame.
Related errors
- MiniMax-H3 takes at most 12 references in total, got {total}
- reference audio needs at least one reference image or video
- width and height must be sent together, or both omitted
- Provide either content_base64 or file_ids, not both
- Provide either content_base64 or file_ids
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/ec52d3b629f8c943.
Report an issue: GitHub.