invoke-ai/InvokeAI · error · ValueError
image size (({image_width}, {image_height})) must be divisib
Error message
image size (({image_width}, {image_height})) must be divisible by {LATENT_SCALE_FACTOR} What it means
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.
Source
Thrown at invokeai/backend/tiles/tiles.py:121
def calc_tiles_even_split(
image_height: int, image_width: int, num_tiles_x: int, num_tiles_y: int, overlap: int = 0
) -> list[Tile]:
"""Calculate the tile coordinates for a given image shape with the number of tiles requested.
Args:
image_height (int): The image height in px.
image_width (int): The image width in px.
num_x_tiles (int): The number of tile to split the image into on the X-axis.
num_y_tiles (int): The number of tile to split the image into on the Y-axis.
overlap (int, optional): The overlap between adjacent tiles in pixels. Defaults to 0.
Returns:
list[Tile]: A list of tiles that cover the image shape. Ordered from left-to-right, top-to-bottom.
"""
# Ensure the image is divisible by LATENT_SCALE_FACTOR
if image_width % LATENT_SCALE_FACTOR != 0 or image_height % LATENT_SCALE_FACTOR != 0:
raise ValueError(f"image size (({image_width}, {image_height})) must be divisible by {LATENT_SCALE_FACTOR}")
# Calculate the tile size based on the number of tiles and overlap, and ensure it's divisible by 8 (rounding down)
if num_tiles_x > 1:
# ensure the overlap is not more than the maximum overlap if we only have 1 tile then we dont care about overlap
assert overlap <= image_width - (LATENT_SCALE_FACTOR * (num_tiles_x - 1))
tile_size_x = LATENT_SCALE_FACTOR * math.floor(
((image_width + overlap * (num_tiles_x - 1)) // num_tiles_x) / LATENT_SCALE_FACTOR
)
assert overlap < tile_size_x
else:
tile_size_x = image_width
if num_tiles_y > 1:
# ensure the overlap is not more than the maximum overlap if we only have 1 tile then we dont care about overlap
assert overlap <= image_height - (LATENT_SCALE_FACTOR * (num_tiles_y - 1))
tile_size_y = LATENT_SCALE_FACTOR * math.floor(
((image_height + overlap * (num_tiles_y - 1)) // num_tiles_y) / LATENT_SCALE_FACTOR
)View on GitHub (pinned to 0b6a024f2f)
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
Example fix
// before tiles = calc_tiles_even_split(image_width=1000, image_height=640, num_tiles=4, overlap=64) // after image_width, image_height = (w // 8) * 8 for w in (1000, 640) # -> 1000→1000? no: use round-down image_width = 1000 - 1000 % 8 # 1000 is divisible by 8; for 642 -> 640 tiles = calc_tiles_even_split(image_width=image_width, image_height=image_height, num_tiles=4, overlap=64)
Defensive patterns
Strategy: validation
Validate before calling
LATENT_SCALE_FACTOR = 8
if image_width % LATENT_SCALE_FACTOR or image_height % LATENT_SCALE_FACTOR:
image_width -= image_width % LATENT_SCALE_FACTOR
image_height -= image_height % LATENT_SCALE_FACTOR
tiles = calc_tiles_even_split(image_width, image_height, num_tiles, overlap) Type guard
def is_latent_aligned(w: int, h: int, factor: int = 8) -> bool:
return w % factor == 0 and h % factor == 0 Try / catch
try:
tiles = calc_tiles_even_split(w, h, num_tiles, overlap)
except ValueError as e:
if "must be divisible" in str(e):
w, h = w - w % 8, h - h % 8
tiles = calc_tiles_even_split(w, h, num_tiles, overlap)
else:
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: User-supplied arbitrary resolutions in the tiled-diffusion invoke path, image resize pipelines producing odd sizes, or tests passing non-aligned dimensions.
Related errors
- Hidden size {params.hidden_size} must be divisible by num_he
- No external provider config fields provided
- str(e)
- str(e) (ValueError from user service update, e.g. LastAdmini
- Current password is required to set a new password
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/1525ab9222b35a35.
Report an issue: GitHub.