{"record":{"id":"4f423953efa665c6","repo":"Comfy-Org/ComfyUI","slug":"resizing-height-x-width-to-target-height-x-t","errorCode":null,"errorMessage":"Resizing [{height}x{width}] to [{target_height}x{target_width}] exceeds the patch budget.","messagePattern":"Resizing \\[(.+?)x(.+?)\\] to \\[(.+?)x(.+?)\\] exceeds the patch budget\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy/text_encoders/gemma4.py","lineNumber":1401,"sourceCode":"    target_px = max_patches * patch_size ** 2\n    factor = math.sqrt(target_px / (height * width))\n    side_mult = pooling_kernel_size * patch_size\n    target_height = math.floor(factor * height / side_mult) * side_mult\n    target_width = math.floor(factor * width / side_mult) * side_mult\n\n    if target_height == 0 and target_width == 0:\n        raise ValueError(f\"Attempting to resize to a 0 x 0 image. Resized height should be divisible by {side_mult}.\")\n\n    max_side_length = (max_patches // pooling_kernel_size ** 2) * side_mult\n    if target_height == 0:\n        target_height = side_mult\n        target_width = min(math.floor(width / height) * side_mult, max_side_length)\n    elif target_width == 0:\n        target_width = side_mult\n        target_height = min(math.floor(height / width) * side_mult, max_side_length)\n\n    if target_height * target_width > target_px:\n        raise ValueError(f\"Resizing [{height}x{width}] to [{target_height}x{target_width}] exceeds the patch budget.\")\n\n    return target_height, target_width\n\n\nclass Gemma4_Tokenizer():\n    tokenizer_json_data = None\n    prime_empty_thought = False\n\n    def state_dict(self):\n        if self.tokenizer_json_data is not None:\n            return {\"tokenizer_json\": self.tokenizer_json_data}\n        return {}\n\n    def _audio_token_count(self, num_samples):\n        # Default (E2B/E4B): mel frames after two stride-2 conv subsamples.\n        _fl = 320  # int(round(16000 * 20.0 / 1000.0))\n        _hl = 160  # int(round(16000 * 10.0 / 1000.0))\n        _nmel = (num_samples + _fl // 2 - (_fl + 1)) // _hl + 1","sourceCodeStart":1383,"sourceCodeEnd":1419,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/text_encoders/gemma4.py#L1383-L1419","documentation":"The companion check in _get_aspect_ratio_preserving_size: after fixing zero sides to side_mult and clamping to max_side_length, the final target area must not exceed target_px = max_patches * patch_size^2. Very elongated images (e.g. panoramas) can still produce target_height * target_width above the budget after the clamping arithmetic, and this ValueError reports source and target sizes.","triggerScenarios":"Feeding extreme aspect-ratio images (wide panoramas, thin strips) to the Gemma4 vision encoder, where the long side capped at max_side_length times the forced short side still exceeds the patch budget; configs with small max_patches relative to the image.","commonSituations":"Panoramic or strip images in multimodal prompts; screenshot-style tall images; users lowering max_patches; defaults tuned for roughly square photos hitting unusual inputs.","solutions":["Crop or letterbox the image to a moderate aspect ratio (near square) before encoding.","Increase max_patches so the budget covers the computed target resolution.","Downscale the long side so that (long/short) ratio times side_mult stays within the budget."],"exampleFix":"# before\nemb = tokenizer.encode_image(panorama)  # 10000x500 -> exceeds patch budget\n\n# after\nh, w = panorama.height, panorama.width\nif w / h > 4:\n    w = h * 4  # crop to 4:1\n    panorama = panorama.crop((0, 0, w, h))\nemb = tokenizer.encode_image(panorama)","handlingStrategy":"validation","validationCode":"target_px = max_patches * patch_size ** 2\nassert height * width <= target_px * 4, f'image {height}x{width} too large/elongated for patch budget {target_px}'","typeGuard":"def fits_patch_budget(h: int, w: int, max_patches: int, patch: int) -> bool:\n    target_px = max_patches * patch * patch\n    max_side = (max_patches // (2 * 2)) * 2 * patch  # pooling=2 example\n    return max(h, w) * min(h, w) <= target_px and max(h, w) <= max_side","tryCatchPattern":"try:\n    h, w = _get_aspect_ratio_preserving_size(height, width, patch_size, max_patches, pooling)\nexcept ValueError as e:\n    if 'patch budget' in str(e):\n        h, w = _get_aspect_ratio_preserving_size(height, height, patch_size, max_patches, pooling)  # crop to square\n    else:\n        raise","preventionTips":["Crop panoramas/strips to moderate aspect ratios before encoding.","Raise max_patches in encoder config when supporting very large images.","Test your image pipeline with extreme aspect ratios before deployment."],"tags":["text-encoder","gemma4","vision","patch-budget","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}