{"record":{"id":"dea21f4821ef3387","repo":"sgl-project/sglang","slug":"minimax-h3-denoise-state-must-be-a-mapping","errorCode":null,"errorMessage":"MiniMax H3 denoise state must be a mapping","messagePattern":"MiniMax H3 denoise state must be a mapping","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/stages/latent_preparation.py","lineNumber":49,"sourceCode":"        return batch\n\n    def run_grouped_requests(\n        self,\n        batches: list[Req],\n        server_args: ServerArgs,\n    ) -> list[Req]:\n        \"\"\"Preserve H3's independent per-modality RNG streams per request.\"\"\"\n        return [self(batch, server_args) for batch in batches]\n\n    @staticmethod\n    def _publish_native_latent_state(batch: Req) -> None:\n        from sglang.multimodal_gen.runtime.pipelines_core.stages.model_specific_stages.minimax_h3.constants import (\n            MINIMAX_H3_DENOISE_STATE_EXTRA_KEY,\n        )\n\n        state = batch.extra.get(MINIMAX_H3_DENOISE_STATE_EXTRA_KEY)\n        if not isinstance(state, dict):\n            raise ValueError(\"MiniMax H3 denoise state must be a mapping\")\n        video_rows = state.get(\"initial_video_rows\")\n        audio_rows = state.get(\"initial_audio_rows\")\n        if not isinstance(video_rows, torch.Tensor) or video_rows.ndim != 2:\n            raise ValueError(\"MiniMax H3 initial_video_rows must be a rank-2 tensor\")\n        if not isinstance(audio_rows, torch.Tensor) or audio_rows.ndim != 2:\n            raise ValueError(\"MiniMax H3 initial_audio_rows must be a rank-2 tensor\")\n\n        latent_t = int(state[\"latent_t\"])\n        latent_h = int(state[\"latent_h\"])\n        latent_w = int(state[\"latent_w\"])\n        audio_t = int(state[\"audio_t\"])\n        batch.latents = video_rows\n        batch.audio_latents = audio_rows\n        batch.raw_latent_shape = (1, 24, latent_t, latent_h, latent_w)\n        batch.raw_audio_latent_shape = (2, 32, audio_t)\n\n    def _prepare_denoise_state_from_plan(self, batch: Req, plan) -> None:\n        \"\"\"Direct initial-noise materialization (t2va recipe):","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/stages/latent_preparation.py#L31-L67","documentation":"The MiniMax H3 latent preparation stage reads a per-batch denoise state from batch.extra under MINIMAX_H3_DENOISE_STATE_EXTRA_KEY and requires it to be a dict. This ValueError fires when the key is missing (extra.get returns None) or holds a non-mapping value, meaning no earlier stage (or the plan-driven preparation path) populated the denoise state for this batch.","triggerScenarios":"forward() runs _publish_native_latent_state while the batch.extra entry for the denoise state is absent or set to a non-dict (e.g. a tensor, list, or None) — typically because _prepare_denoise_state_from_plan skipped preparation or an upstream stage overwrote the key.","commonSituations":"A pipeline assembled without the MiniMax H3 latent preparation stage, replaying cached batches whose extra payload was serialized/deserialized into a non-dict, or another stage writing an incompatible value under the same extra key.","solutions":["Ensure the batch passed a resolved plan so _prepare_denoise_state_from_plan populates MINIMAX_H3_DENOISE_STATE_EXTRA_KEY before latent publication","Check nothing upstream deletes or overwrites batch.extra[MINIMAX_H3_DENOISE_STATE_EXTRA_KEY]","If injecting state manually, set it to a dict containing initial_video_rows and initial_audio_rows as rank-2 tensors"],"exampleFix":"// before\nbatch.extra[MINIMAX_H3_DENOISE_STATE_EXTRA_KEY] = video_noise_tensor\n// after\nbatch.extra[MINIMAX_H3_DENOISE_STATE_EXTRA_KEY] = {\n    \"initial_video_rows\": video_noise,   # rank-2 tensor\n    \"initial_audio_rows\": audio_noise,   # rank-2 tensor\n    \"latent_t\": latent_t, \"latent_h\": latent_h, \"latent_w\": latent_w,\n    \"audio_t\": audio_t,\n}","handlingStrategy":"validation","validationCode":"state = batch.extra.get(MINIMAX_H3_DENOISE_STATE_EXTRA_KEY)\nif not isinstance(state, dict):\n    raise RuntimeError(\"run latent preparation stage (plan resolution) before forward\")","typeGuard":"def has_minimax_h3_denoise_state(batch) -> bool:\n    state = batch.extra.get(MINIMAX_H3_DENOISE_STATE_EXTRA_KEY)\n    return isinstance(state, dict) and \"initial_video_rows\" in state and \"initial_audio_rows\" in state","tryCatchPattern":null,"preventionTips":["Always route requests through the latent preparation stage before forward","Never store non-dict values under MINIMAX_H3_DENOISE_STATE_EXTRA_KEY"],"tags":["minimax-h3","pipeline","batch-state","validation"],"backgroundTag":"pipeline-stage-state-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}