{"record":{"id":"b39a17ec1e1ba578","repo":"unslothai/unsloth","slug":"minimax-h3-takes-at-most-12-references-in-total-g","errorCode":null,"errorMessage":"MiniMax-H3 takes at most 12 references in total, got {total}","messagePattern":"MiniMax-H3 takes at most 12 references in total, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"studio/backend/models/inference.py","lineNumber":3786,"sourceCode":"\n    @field_validator(\"reference_images\", \"reference_audios\")\n    @classmethod\n    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","sourceCodeStart":3768,"sourceCodeEnd":3804,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/inference.py#L3768-L3804","documentation":"Raised by a Pydantic model_validator on VideoGenerateRequest for the MiniMax-H3 video model. The model accepts three kinds of reference inputs (reference_images, reference_videos, reference_audios) but enforces a combined budget of 12 items across all three. The check runs after field validation, so it fires only when the summed count exceeds 12. Pydantic surfaces it as a ValidationError (typically HTTP 422 in FastAPI) with the offending total embedded in the message.","triggerScenarios":"POST to the video generation endpoint with any combination of reference_images + reference_videos + reference_audios whose lengths sum to 13 or more, e.g. 8 reference_images + 4 reference_videos + 2 reference_audios (total 14). Each list alone may be under 12; only the combined total triggers it.","commonSituations":"Building a multi-shot storyboard pipeline that attaches one image per scene shot; batching all reference assets into a single generate call instead of splitting into multiple requests; UI layers that let users attach unlimited references before submit.","solutions":["Reduce the combined reference count to 12 or fewer by removing the least important items from reference_images / reference_videos / reference_audios.","Split the generation into multiple requests, each with at most 12 references, and stitch the results.","If you genuinely need more references, check whether a different model family without this cap applies to your use case.","Add a client-side counter over the three arrays before submitting so users get feedback in the UI."],"exampleFix":"// before\nreq = {\n  \"prompt\": p,\n  \"reference_images\": imgs,   // 10 items\n  \"reference_videos\": vids,   // 3 items\n}\n// after\nreq = {\n  \"prompt\": p,\n  \"reference_images\": imgs[:10],\n  \"reference_videos\": vids[:2],  // total <= 12\n}","handlingStrategy":"validation","validationCode":"def reference_count(req: dict) -> int:\n    return sum(len(req.get(k) or []) for k in (\"reference_images\", \"reference_videos\", \"reference_audios\"))\n\ndef fits_reference_budget(req: dict) -> bool:\n    return reference_count(req) <= 12","typeGuard":"function isSubmittableVideoRequest(req: unknown): boolean {\n  const r = req as Record<string, unknown[]>;\n  const n = (r.reference_images?.length ?? 0) + (r.reference_videos?.length ?? 0) + (r.reference_audios?.length ?? 0);\n  return n <= 12;\n}","tryCatchPattern":"try { await client.generate(req) } catch (e) { if (e instanceof ValidationError && e.message.includes('at most 12 references')) trimAndRetry(req); else throw e; }","preventionTips":["Show a live reference counter (used 12 max) in the upload UI","Cap attachment lists client-side before submit","Log the three list lengths on every rejected request"],"tags":["pydantic","validation","video-generation","minimax"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}