invoke-ai/InvokeAI · error
Cannot achieve the target of num_channels={num_channels}.
Error message
Cannot achieve the target of num_channels={num_channels}. What it means
prepare_control_image slices the resized control-image tensor down to exactly `num_channels`. If the tensor has fewer channels than requested (or num_channels is <= 0), the target channel count is unreachable and this ValueError is raised instead of silently producing a malformed control input.
Source
Thrown at invokeai/app/util/controlnet_utils.py:426
nimage = np.array(nimage).astype(np.float32) / 255.0
nimage = nimage.transpose(0, 3, 1, 2)
timage = torch.from_numpy(nimage)
# use fancy lvmin controlnet resizing
elif resize_mode == "just_resize" or resize_mode == "crop_resize" or resize_mode == "fill_resize":
nimage = np.array(image)
timage, nimage = np_img_resize(
np_img=nimage,
resize_mode=resize_mode,
h=height,
w=width,
device=torch.device(device),
)
else:
raise ValueError(f"Unsupported resize_mode: '{resize_mode}'.")
if timage.shape[1] < num_channels or num_channels <= 0:
raise ValueError(f"Cannot achieve the target of num_channels={num_channels}.")
timage = timage[:, :num_channels, :, :]
timage = timage.to(device=device, dtype=dtype)
cfg_injection = control_mode == "more_control" or control_mode == "unbalanced"
if do_classifier_free_guidance and not cfg_injection:
timage = torch.cat([timage] * 2)
return timage
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Check the control image's channel count and convert it to RGB (3 channels) before passing it in
- Verify the ControlNet/T2I-Adapter model config has a correct positive channels field; re-import or fix the model record
- Ensure the resize_mode branch you took actually produces a tensor with >= num_channels channels
- Pass an explicit valid num_channels when calling prep_control_data instead of deriving it from a bad config
Example fix
// before
img = Image.open('mask.png') # mode 'L', 1 channel
control_data = prep_control_data(..., control_image=img, ...) # ValueError
// after
img = Image.open('mask.png').convert('RGB')
control_data = prep_control_data(..., control_image=img, ...) Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
from PIL import Image
def ensure_channels_ok(image, num_channels):
if num_channels is None or num_channels <= 0:
raise ValueError(f"num_channels must be positive, got {num_channels}")
arr = np.asarray(Image.open(image) if isinstance(image, str) else image)
if arr.ndim == 2:
ch = 1
elif arr.shape[-1] in (1, 2, 3, 4):
ch = arr.shape[-1]
else:
ch = 3
if ch < num_channels:
raise ValueError(f"image has {ch} channels; need {num_channels}") Type guard
def has_enough_channels(t, num_channels):
return num_channels > 0 and t.dim() >= 3 and t.shape[1] >= num_channels Try / catch
try:
control_data = prep_control_data(..., control_image=img, ...)
except ValueError as e:
if 'num_channels' in str(e):
img = img.convert('RGB')
control_data = prep_control_data(..., control_image=img, ...)
else:
raise Prevention
- Always .convert('RGB') control images before passing them in
- Never hand-set num_channels; take it from the model's config
- Validate model imports so channels fields cannot be 0/negative
When it happens
Trigger: Calling prep_control_data / run_t2i_adapters / prepare_controlnet_cond with a control image whose effective channel count after resizing is less than the model's required channels (e.g. 1-channel or 4-channel image against 3 channels required is fine, but 3-channel against 4 required fails), or passing num_channels <= 0 via a misconfigured ControlNet/T2I-Adapter model field.
Common situations: Using a grayscale single-channel control image with a model expecting more channels; a ControlNet model record whose target channels value is 0 or negative due to a bad/legacy config; feeding an alpha-only PNG loaded with 2 channels.
Related errors
- Invalid mode selected
- Unexpected control_input type: ${type(control_input)}
- Unsupported control_lllite type: {type(control_lllite)}
- The Anima ControlNet-LLLite model '{lllite_field.control_mod
- This Anima ControlNet-LLLite adapter is an inpainting adapte
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/0013c626d83b40b7.
Report an issue: GitHub.