{"record":{"id":"7079a4768b3dffb2","repo":"unslothai/unsloth","slug":"reference-audio-needs-at-least-one-reference-image","errorCode":null,"errorMessage":"reference audio needs at least one reference image or video to go with","messagePattern":"reference audio needs at least one reference image or video to go with","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"studio/backend/models/inference.py","lineNumber":3789,"sourceCode":"    def _bounded_reference_media(cls, value: Optional[list[str]]) -> Optional[list[str]]:\n        # Bound each item like first_frame, so a list cannot buffer what one field may not.\n        if value is not None:\n            for item in value:\n                if len(item) > 32 * 1024 * 1024:\n                    raise ValueError(\"each reference must be at most 32 MiB (base64)\")\n        return value\n\n    @model_validator(mode = \"after\")\n    def _references_fit_the_models_budget(self) -> \"VideoGenerateRequest\":\n        images = self.reference_images or []\n        videos = self.reference_videos or []\n        audios = self.reference_audios or []\n        total = len(images) + len(videos) + len(audios)\n        if total > 12:\n            raise ValueError(f\"MiniMax-H3 takes at most 12 references in total, got {total}\")\n        # Standalone audio must accompany an image or video reference.\n        if audios and not images and not videos:\n            raise ValueError(\n                \"reference audio needs at least one reference image or video to go with\"\n            )\n        if (images or videos or audios) and (self.first_frame or self.last_frame):\n            raise ValueError(\n                \"keyframes and references cannot be combined: MiniMax-H3 runs them against \"\n                \"different denoiser partitions\"\n            )\n        return self\n\n    @model_validator(mode = \"after\")\n    def _keyframe_canvas_needs_both_axes(self) -> \"VideoGenerateRequest\":\n        # Omit both axes for \"match source\", or provide both for an explicit canvas.\n        # KEYFRAME requests only. There a half-specified canvas is silently discarded:\n        # _resolve_keyframes matches the source aspect whenever either axis is missing, so the\n        # axis that was sent never reaches the render and the API would accept one recipe and\n        # draw another. Without a keyframe the backend deliberately resolves the missing axis\n        # from the family's default preset -- validate_video_request_shape and generate() both\n        # document and implement that -- so applying the rule to every request would reject","sourceCodeStart":3771,"sourceCodeEnd":3807,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/inference.py#L3771-L3807","documentation":"Raised by the same model_validator on VideoGenerateRequest (MiniMax-H3). MiniMax-H3 treats reference audio as a modifier of an image or video reference, not a standalone conditioning input, so the request must include at least one reference_image or reference_video whenever reference_audios is non-empty. The check deliberately runs after the 12-item budget check, so a 13-item standalone-audio request fails with the budget error first. It surfaces as a Pydantic ValidationError / HTTP 422.","triggerScenarios":"POST to the video generation endpoint with a non-empty reference_audios array while both reference_images and reference_videos are empty or omitted, e.g. {\"prompt\": p, \"reference_audios\": [\"data:audio/mp3;base64,...\"]} with no visual reference.","commonSituations":"Trying to do audio-driven or music-driven video generation with no visual anchor; porting a workflow from another API where standalone audio conditioning is supported; forgetting to attach the image that was supposed to accompany a voiceover reference.","solutions":["Add at least one reference_image or reference_video to the same request alongside the audio.","If your intent was audio-only generation, use a dedicated audio endpoint/model instead of video generation.","If the audio was meant to set the soundtrack, check whether the model exposes a separate soundtrack/music parameter that composes with prompt-only requests."],"exampleFix":"# before\nreq = {\n  \"prompt\": p,\n  \"reference_audios\": [audio_b64],\n}\n# after\nreq = {\n  \"prompt\": p,\n  \"reference_images\": [image_b64],  # visual anchor required\n  \"reference_audios\": [audio_b64],\n}","handlingStrategy":"validation","validationCode":"def audio_has_visual_anchor(req: dict) -> bool:\n    has_audio = bool(req.get(\"reference_audios\"))\n    has_visual = bool(req.get(\"reference_images\") or req.get(\"reference_videos\"))\n    return not has_audio or has_visual","typeGuard":"function audioOk(req: { reference_audios?: unknown[]; reference_images?: unknown[]; reference_videos?: unknown[] }): boolean {\n  const audio = (req.reference_audios?.length ?? 0) > 0;\n  const visual = (req.reference_images?.length ?? 0) + (req.reference_videos?.length ?? 0) > 0;\n  return !audio || visual;\n}","tryCatchPattern":"try { await client.generate(req) } catch (e) { if (/reference audio needs/.test(String(e))) throw new UserError('Attach an image or video with the audio'); else throw e; }","preventionTips":["Disable the audio-reference UI control until at least one visual reference is attached","Document that audio references are modifiers, not standalone conditioning"],"tags":["pydantic","validation","video-generation","audio","minimax"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}