Comfy-Org/ComfyUI · error · ValueError

Custom alpha video frame count ({mask.shape[0]}) does not ma

Error message

Custom alpha video frame count ({mask.shape[0]}) does not match the source video frame count ({source_frame_count}). The Beeble API requires one mask per source frame.

What it means

In custom alpha mode Beeble needs one mask frame per source video frame. The node encodes the MASK batch as a grayscale H.264 MP4 and validates that mask.shape[0] equals the source video's frame count before upload; a mismatch would desynchronize the matte from the video.

Source

Thrown at comfy_api_nodes/nodes_beeble.py:78

async def _upload_mask_batch_as_video(
    cls: type[IO.ComfyNode],
    mask: Input.Image,
    *,
    frame_rate: Fraction,
    source_frame_count: int,
    wait_label: str,
) -> str:
    """Encode a MASK batch (N, H, W) as a grayscale H.264 MP4 at frame_rate and upload.

    The matte is always downscaled to the pixel budget so it stays within Beeble's limit and
    keeps the same dimensions as the (similarly downscaled) source — both use the same algorithm
    from the same starting dimensions, and downscaling is a no-op when already within budget.
    """
    if mask.dim() == 2:
        mask = mask.unsqueeze(0)
    if mask.shape[0] != source_frame_count:
        raise ValueError(
            f"Custom alpha video frame count ({mask.shape[0]}) does not match the "
            f"source video frame count ({source_frame_count}). The Beeble API requires "
            "one mask per source frame."
        )
    images = downscale_image_tensor(convert_mask_to_image(mask), _MAX_PIXELS)
    alpha_video = InputImpl.VideoFromComponents(Types.VideoComponents(images=images, audio=None, frame_rate=frame_rate))
    return await upload_video_to_comfyapi(cls, alpha_video, wait_label=wait_label)


def _alpha_mode_input(*, video: bool) -> IO.DynamicCombo.Input:
    """Build the alpha_mode DynamicCombo with mode-specific extra inputs."""
    select_keyframe_tooltip = (
        "First-frame keyframe mask. Beeble propagates this across the video." if video else "Grayscale keyframe mask."
    )
    custom_tooltip = (
        "Per-frame grayscale mask covering the entire video. "
        "Must have the same frame count as the source. "
        "Connect a MASK output from SAM3_TrackToMask or similar."

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Regenerate the mask from the exact source video so frame counts match.
  2. Repeat/interpolate the mask to the source frame count: mask = mask.repeat(source_frame_count, 1, 1) for a constant matte.
  3. Re-check the source video's frame count after any trimming or frame-rate change and re-export the matte.

Example fix

# before
alpha = single_frame_mask          # shape (1, H, W), video has 120 frames -> ValueError

# after
alpha = single_frame_mask.repeat(source_frame_count, 1, 1)  # constant matte for all frames
Defensive patterns

Strategy: validation

Validate before calling

if mask.dim() == 2:
    mask = mask.unsqueeze(0)
assert mask.shape[0] == source_frame_count, (
    f"mask frames {mask.shape[0]} != source {source_frame_count}"
)

Type guard

def mask_matches_video(mask, source_frame_count: int) -> bool:
    m = mask if mask.dim() == 3 else mask.unsqueeze(0)
    return m.shape[0] == source_frame_count

Try / catch

try:
    out = await beeble_node(alpha_mode="custom", custom_alpha=mask)
except ValueError as e:
    if "frame count" in str(e):
        mask = mask.repeat(source_frame_count, 1, 1)
        out = await beeble_node(alpha_mode="custom", custom_alpha=mask)

Prevention

When it happens

Trigger: Calling the Beeble node with alpha_mode='custom' where the connected MASK batch (N,H,W after unsqueeze for 2D) has N != source video frame count — e.g. mask generated from a different clip, a still mask of 1 frame, or a trimmed video.

Common situations: Reusing a matte generated for another video; source video trimmed/keyframed after the mask was made; single-frame mask connected to a multi-frame video.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/9f37b8446f0d551b. Report an issue: GitHub.