{"record":{"id":"a6f5429dc5e86777","repo":"sgl-project/sglang","slug":"ref2va-requires-at-least-one-image-reference","errorCode":null,"errorMessage":"ref2va requires at least one image reference","messagePattern":"ref2va requires at least one image reference","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/reference_encoding.py","lineNumber":858,"sourceCode":"    batch.extra[MINIMAX_H3_PREPARED_REFERENCE_VIDEO_EXTRA_KEY] = prepared\n    return prepared\n\n\ndef minimax_h3_prepared_reference_image(batch: Any, plan: Any) -> dict[str, Any]:\n    \"\"\"Resize ref2va image references to their pre-queue-resolved shapes.\n\n    Qwen (pixel_values) and the visual-condition tokenizer consume the identical\n    prepared image. The runtime never recomputes geometry from ``plan.shape``;\n    it consumes the per-material width/height admitted before queueing.\n    \"\"\"\n    cached = batch.extra.get(MINIMAX_H3_PREPARED_REFERENCE_IMAGE_EXTRA_KEY)\n    if cached is not None:\n        return cached\n    images = [\n        m for m in plan.materials if m.material_chain == \"image.reference_preserve\"\n    ]\n    if not images:\n        raise ValueError(\"ref2va requires at least one image reference\")\n    from PIL import Image, ImageOps\n\n    from sglang.multimodal_gen.runtime.pipelines_core.stages.model_specific_stages.minimax_h3.material_io import (\n        minimax_h3_localize_material_uri,\n    )\n\n    prepared_images = []\n    for material in images:\n        from sglang.multimodal_gen.runtime.pipelines_core.stages.model_specific_stages.minimax_h3.prequeue import (\n            MINIMAX_H3_PROBE_FACTS_EXTRA_KEY,\n            MINIMAX_H3_RESOLVED_MATERIAL_SHAPES_EXTRA_KEY,\n        )\n\n        condition_index = int(material.condition_index)\n        source_facts = batch.extra.get(MINIMAX_H3_PROBE_FACTS_EXTRA_KEY, {}).get(\n            condition_index\n        )\n        resolved_shape = batch.extra.get(","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/reference_encoding.py#L840-L876","documentation":"The ref2va partition requires at least one material with material_chain == 'image.reference_preserve' to build its reference image conditioning. If the plan contains none, minimax_h3_prepared_reference_image refuses to proceed.","triggerScenarios":"Sending a request to the ref2va model with no image reference attached (text-only, or only audio/video materials), reaching _encode_ref2va/_encode_reference_image.","commonSituations":"Users assuming image references are optional for the reference-preserving model, or a client dropping the image attachment on serialization.","solutions":["Attach at least one image reference (material_chain 'image.reference_preserve') to the request","Route text-only or no-image requests to the fl2va partition instead","Validate request shape against the loaded partition's declared tasks/materials before enqueueing"],"exampleFix":"// before\nrequest(materials=[video_material])  # ref2va -> ValueError\n\n// after\nrequest(materials=[image_material, video_material])","handlingStrategy":"validation","validationCode":"def ref2va_ready(plan) -> bool:\n    return any(m.material_chain == \"image.reference_preserve\" for m in plan.materials)","typeGuard":"def has_image_reference(plan) -> bool:\n    return any(m.material_chain == \"image.reference_preserve\" for m in plan.materials)","tryCatchPattern":null,"preventionTips":["Gate ref2va requests on the presence of an image reference","Route no-image requests to fl2va"],"tags":["minimax-h3","ref2va","missing-input"],"backgroundTag":"missing-required-input","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}