Comfy-Org/ComfyUI · error · ValueError
Expected torch.Tensor, got {type(img_tensor)}
Error message
Expected torch.Tensor, got {type(img_tensor)} What it means
The dataset-save helper accepts either PIL Images or torch tensors per item; when an item is neither, the else branch raises naming the actual type. The preceding code already handles tensors including CHW->HWC permute, so this error specifically means the iterable passed as images contains a foreign object (str path, numpy array, list, None).
Source
Thrown at comfy_extras/nodes_dataset.py:432
img_tensor = img_tensor.squeeze(0)
# If tensor is [C, H, W], permute to [H, W, C]
if img_tensor.dim() == 3 and img_tensor.shape[0] in [1, 3, 4]:
if (
img_tensor.shape[0] <= 4
and img_tensor.shape[1] > 4
and img_tensor.shape[2] > 4
):
img_tensor = img_tensor.permute(1, 2, 0)
# Convert to numpy and scale to 0-255
img_array = img_tensor.cpu().numpy()
img_array = np.clip(img_array * 255.0, 0, 255).astype(np.uint8)
# Convert to PIL Image
img = Image.fromarray(img_array)
else:
raise ValueError(f"Expected torch.Tensor, got {type(img_tensor)}")
# Save image
if overwrite:
filename = f"{prefix}_{idx:05d}.png"
else:
_, _, counter, _, resolved_prefix = folder_paths.get_save_image_path(prefix, output_dir)
filename = f"{resolved_prefix}_{counter:05}_{idx:05d}.png"
filepath = os.path.join(output_dir, filename)
img.save(filepath)
saved_files.append(filename)
return saved_files
class SaveImageDataSetToFolderNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Convert every item to a torch tensor before saving: torch.from_numpy(arr) for numpy, PILToTensor for images.
- Filter out None/str entries before passing the list.
- Check the upstream node's declared output type and insert the appropriate conversion node.
Example fix
# before images = [np.array(pil_img)] # after images = [torch.from_numpy(np.array(pil_img)).permute(2, 0, 1)]
Defensive patterns
Strategy: type-guard
Validate before calling
import torch, numpy as np
def coerce_item(x):
if isinstance(x, torch.Tensor):
return x
if isinstance(x, np.ndarray):
return torch.from_numpy(x)
if hasattr(x, "convert"): # PIL
return PILToTensor()(x)
raise TypeError(f"cannot coerce {type(x)!r}") Type guard
def is_savable(x) -> bool:
return hasattr(x, "save") or isinstance(x, torch.Tensor) Try / catch
try:
save_dataset(images)
except ValueError as e:
if "Expected torch.Tensor" in str(e):
images = [coerce_item(x) for x in images]
save_dataset(images)
else:
raise Prevention
- Convert numpy/PIL to tensors at the boundary, not at save time.
- Filter None and str entries out of image lists before saving.
- Re-check upstream node output types after upgrading custom nodes.
When it happens
Trigger: Passing a list containing numpy arrays, file-path strings, or None instead of torch.Tensor / PIL.Image entries — e.g. feeding raw generator output lists or JSON-derived structures straight into the save-dataset node.
Common situations: Version drift where an upstream node changed output from tensors to numpy or to a dict payload; user scripts assembling the list manually and forgetting conversions; None placeholders for skipped items.
Related errors
- No valid images found in input
- Invalid folder name {folder_name!r}: resolves outside of {ba
- folder_name must name a subfolder of the datasets directory,
- Dataset folder {folder_name!r} not found in: {', '.join(root
- No video files found in {sub_input_dir}
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/5c5765413c4f39a7.
Report an issue: GitHub.