{"record":{"id":"1525ab9222b35a35","repo":"invoke-ai/InvokeAI","slug":"image-size-image-width-image-height-must","errorCode":null,"errorMessage":"image size (({image_width}, {image_height})) must be divisible by {LATENT_SCALE_FACTOR}","messagePattern":"image size \\(\\((.+?), (.+?)\\)\\) must be divisible by (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/tiles/tiles.py","lineNumber":121,"sourceCode":"\ndef calc_tiles_even_split(\n    image_height: int, image_width: int, num_tiles_x: int, num_tiles_y: int, overlap: int = 0\n) -> list[Tile]:\n    \"\"\"Calculate the tile coordinates for a given image shape with the number of tiles requested.\n\n    Args:\n        image_height (int): The image height in px.\n        image_width (int): The image width in px.\n        num_x_tiles (int): The number of tile to split the image into on the X-axis.\n        num_y_tiles (int): The number of tile to split the image into on the Y-axis.\n        overlap (int, optional): The overlap between adjacent tiles in pixels. Defaults to 0.\n\n    Returns:\n        list[Tile]: A list of tiles that cover the image shape. Ordered from left-to-right, top-to-bottom.\n    \"\"\"\n    # Ensure the image is divisible by LATENT_SCALE_FACTOR\n    if image_width % LATENT_SCALE_FACTOR != 0 or image_height % LATENT_SCALE_FACTOR != 0:\n        raise ValueError(f\"image size (({image_width}, {image_height})) must be divisible by {LATENT_SCALE_FACTOR}\")\n\n    # Calculate the tile size based on the number of tiles and overlap, and ensure it's divisible by 8 (rounding down)\n    if num_tiles_x > 1:\n        # ensure the overlap is not more than the maximum overlap if we only have 1 tile then we dont care about overlap\n        assert overlap <= image_width - (LATENT_SCALE_FACTOR * (num_tiles_x - 1))\n        tile_size_x = LATENT_SCALE_FACTOR * math.floor(\n            ((image_width + overlap * (num_tiles_x - 1)) // num_tiles_x) / LATENT_SCALE_FACTOR\n        )\n        assert overlap < tile_size_x\n    else:\n        tile_size_x = image_width\n\n    if num_tiles_y > 1:\n        # ensure the overlap is not more than the maximum overlap if we only have 1 tile then we dont care about overlap\n        assert overlap <= image_height - (LATENT_SCALE_FACTOR * (num_tiles_y - 1))\n        tile_size_y = LATENT_SCALE_FACTOR * math.floor(\n            ((image_height + overlap * (num_tiles_y - 1)) // num_tiles_y) / LATENT_SCALE_FACTOR\n        )","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/tiles/tiles.py#L103-L139","documentation":"calc_tiles_even_split requires the image dimensions to be divisible by LATENT_SCALE_FACTOR (8) so tiles align to the latent grid. Non-divisible width or height raises this ValueError before any tile math runs.","triggerScenarios":"Calling calc_tiles_even_split(image_width, image_height, num_tiles, ...) where image_width % 8 != 0 or image_height % 8 != 0, e.g. a 1000x640 or arbitrary user-resized image.","commonSituations":"User-supplied arbitrary resolutions in the tiled-diffusion invoke path, image resize pipelines producing odd sizes, or tests passing non-aligned dimensions.","solutions":["Round/pad the image dimensions to the nearest multiple of 8 before tiling","Resize or center-crop the image to an 8-divisible size","Catch the ValueError and rescale the image before invoking"],"exampleFix":"// before\ntiles = calc_tiles_even_split(image_width=1000, image_height=640, num_tiles=4, overlap=64)\n// after\nimage_width, image_height = (w // 8) * 8 for w in (1000, 640)  # -> 1000→1000? no: use round-down\nimage_width = 1000 - 1000 % 8  # 1000 is divisible by 8; for 642 -> 640\ntiles = calc_tiles_even_split(image_width=image_width, image_height=image_height, num_tiles=4, overlap=64)","handlingStrategy":"validation","validationCode":"LATENT_SCALE_FACTOR = 8\nif image_width % LATENT_SCALE_FACTOR or image_height % LATENT_SCALE_FACTOR:\n    image_width -= image_width % LATENT_SCALE_FACTOR\n    image_height -= image_height % LATENT_SCALE_FACTOR\ntiles = calc_tiles_even_split(image_width, image_height, num_tiles, overlap)","typeGuard":"def is_latent_aligned(w: int, h: int, factor: int = 8) -> bool:\n    return w % factor == 0 and h % factor == 0","tryCatchPattern":"try:\n    tiles = calc_tiles_even_split(w, h, num_tiles, overlap)\nexcept ValueError as e:\n    if \"must be divisible\" in str(e):\n        w, h = w - w % 8, h - h % 8\n        tiles = calc_tiles_even_split(w, h, num_tiles, overlap)\n    else:\n        raise","preventionTips":["Normalize all image dimensions to multiples of 8 at ingest","Add a resize/pad step in the tiled-diffusion pre-processing","Write unit tests with odd resolutions to catch misalignment early"],"tags":["validation","tiling","image-processing","divisibility"],"backgroundTag":"dimension-not-divisible","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}