{"record":{"id":"3554cea56899d05e","repo":"invoke-ai/InvokeAI","slug":"height-and-width-must-be-divisible-by-pixels-per","errorCode":null,"errorMessage":"height and width must be divisible by {PIXELS_PER_IMAGE_TOKEN}, got {height}x{width}","messagePattern":"height and width must be divisible by (.+?), got (.+?)x(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/ideogram4/sampling_utils.py","lineNumber":48,"sourceCode":"LATENT_DIM = 128\n\n\nclass Ideogram4DenoiseInputs(TypedDict):\n    \"\"\"The packed-sequence tensors fed to the transformer during denoising.\"\"\"\n\n    position_ids: torch.Tensor  # (1, L, 3) int64 — (t, h, w) positions for MRoPE\n    segment_ids: torch.Tensor  # (1, L) int64 — sample id within the packed batch\n    indicator: torch.Tensor  # (1, L) int64 — LLM_TOKEN_INDICATOR or OUTPUT_IMAGE_INDICATOR\n    num_text_tokens: int\n    num_image_tokens: int\n    grid_h: int\n    grid_w: int\n\n\ndef validate_dimensions(height: int, width: int) -> None:\n    \"\"\"Ensure the requested resolution is compatible with the patch/VAE grid.\"\"\"\n    if height % PIXELS_PER_IMAGE_TOKEN != 0 or width % PIXELS_PER_IMAGE_TOKEN != 0:\n        raise ValueError(f\"height and width must be divisible by {PIXELS_PER_IMAGE_TOKEN}, got {height}x{width}\")\n\n\ndef build_denoise_inputs(\n    num_text_tokens: int,\n    height: int,\n    width: int,\n    device: torch.device,\n) -> Ideogram4DenoiseInputs:\n    \"\"\"Build the packed ``[text][image]`` position/segment/indicator tensors for one image.\n\n    Mirrors ``Ideogram4Pipeline._build_inputs`` for batch size 1 (no padding).\n    \"\"\"\n    validate_dimensions(height, width)\n    grid_h = height // PIXELS_PER_IMAGE_TOKEN\n    grid_w = width // PIXELS_PER_IMAGE_TOKEN\n    num_image_tokens = grid_h * grid_w\n    total_seq_len = num_text_tokens + num_image_tokens\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/ideogram4/sampling_utils.py#L30-L66","documentation":"validate_dimensions checks that requested height and width are multiples of PIXELS_PER_IMAGE_TOKEN, because Ideogram4 packs pixels into patch/token grids; non-divisible sizes would break the patchify/VAE grid math.","triggerScenarios":"Calling build_denoise_inputs (or any caller of validate_dimensions) with an arbitrary resolution like 1023x767 instead of a multiple of PIXELS_PER_IMAGE_TOKEN.","commonSituations":"User-typed custom resolutions in a UI, aspect-ratio presets from other models (e.g. SD sizes like 512x512 when the token size differs), rounding errors when scaling dimensions.","solutions":["Round height and width down/up to the nearest multiple of PIXELS_PER_IMAGE_TOKEN before calling","Use one of the model's supported resolution presets","Derive dimensions from a base size multiplied by an integer factor"],"exampleFix":"// before\nbuild_denoise_inputs(tokens, 1023, 767)\n// after\nppit = PIXELS_PER_IMAGE_TOKEN\nh, w = (1023 // ppit) * ppit, (767 // ppit) * ppit\nbuild_denoise_inputs(tokens, h, w)","handlingStrategy":"validation","validationCode":"def snap_to_token_grid(h, w, step=PIXELS_PER_IMAGE_TOKEN):\n    return max(step, (h // step) * step), max(step, (w // step) * step)\nheight, width = snap_to_token_grid(height, width)","typeGuard":"def is_valid_resolution(h: int, w: int) -> bool:\n    return h % PIXELS_PER_IMAGE_TOKEN == 0 and w % PIXELS_PER_IMAGE_TOKEN == 0","tryCatchPattern":"try:\n    build_denoise_inputs(num_text_tokens, height, width)\nexcept ValueError as e:\n    if \"divisible by\" in str(e):\n        height, width = snap_to_token_grid(height, width)\n        build_denoise_inputs(num_text_tokens, height, width)\n    else:\n        raise","preventionTips":["Always derive dimensions from multiples of PIXELS_PER_IMAGE_TOKEN","Use preset resolution lists instead of free-form user input","Round user resolutions to the grid automatically in UI code"],"tags":["validation","dimensions","resolution"],"backgroundTag":"dimension-not-divisible","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}