{"record":{"id":"91f06421ee609b5d","repo":"sgl-project/sglang","slug":"z-image-batch-must-contain-at-least-one-image-late","errorCode":null,"errorMessage":"Z-Image batch must contain at least one image latent","messagePattern":"Z-Image batch must contain at least one image latent","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/zimage.py","lineNumber":975,"sourceCode":"        patch_size: int,\n        f_patch_size: int,\n        image_seq_len_target: int | None = None,\n        caption_valid_lens: torch.Tensor | None = None,\n        caption_valid_mask: torch.Tensor | None = None,\n    ):\n        \"\"\"Patchify images and pad image/caption tokens to batch targets.\n\n        Each image is [C, F, H, W] and has one [L, D] caption. Returned tensors\n        are stacked as [B, S, D], while valid lengths keep track of real tokens\n        before learned pad tokens are restored. `image_seq_len_target`, when\n        set, is the SP-local padded image-token target.\n        \"\"\"\n        if len(all_image) != len(all_cap_feats):\n            raise ValueError(\n                f\"Z-Image expects one caption embedding per image, got {len(all_image)} images and {len(all_cap_feats)} captions\"\n            )\n        if not all_image:\n            raise ValueError(\"Z-Image batch must contain at least one image latent\")\n        if caption_valid_mask is not None and caption_valid_mask.shape[0] != len(\n            all_cap_feats\n        ):\n            raise ValueError(\"caption_valid_mask must have one row per Z-Image caption\")\n\n        pH = pW = patch_size\n        pF = f_patch_size\n        all_image_out = []\n        all_image_size = []\n        all_cap_feats_out = []\n        all_image_valid_lens = []\n        all_cap_valid_lens = []\n        all_cap_valid_masks = []\n        all_image_attn_lens = []\n        all_cap_attn_lens = []\n        image_records = []\n\n        cap_seq_len_target = max(","sourceCodeStart":957,"sourceCodeEnd":993,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/zimage.py#L957-L993","documentation":"Raised by ZImage.patchify_and_embed when all_image is empty. The forward path requires at least one image latent to embed; an empty batch has no valid work and downstream stacking would produce degenerate tensors.","triggerScenarios":"Calling Z-Image forward with an empty list of image latents — e.g. all samples in the micro-batch were filtered out or the request batch was empty.","commonSituations":"A scheduler/filter step removed every sample (failed VAE encode, safety filter) leaving an empty batch that still reaches the model.","solutions":["Skip the forward call when the batch is empty instead of invoking the model","Fix upstream filtering so at least one valid image/caption pair survives, or return early"],"exampleFix":"# before\nif not batch: pass  # falls through to model\nout = model(all_image=[], all_cap_feats=[])\n# after\nif not batch:\n    return []\nout = model(all_image=batch_images, all_cap_feats=batch_caps)","handlingStrategy":"type-guard","validationCode":"if not all_image:\n    return []  # skip model call for empty batch","typeGuard":"def is_nonempty_batch(images: list) -> bool:\n    return len(images) > 0","tryCatchPattern":null,"preventionTips":["Early-return on empty batches in the scheduler before reaching the model"],"tags":["z-image","empty-batch","validation"],"backgroundTag":"empty-input-batch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}