Nodes/Mask Tensor I/O/Load Mask Tensor
ComfyUI Node

Load Mask Tensor

Get yesterday's mask back, in full float precision

By swanjohn99·Created a day ago·Updated about 13 hours ago· 0
Load Mask Tensor
    • masks
    mask_file
    subfoldermasks

    This is the other half of the deal, and it's the half that actually saves you time. You ran SAM 3 over a clip, saved the mask with Save Mask Tensor, and now you want to change the inpaint prompt without sitting through segmentation again. Load Mask Tensor reads that .pt file straight off disk and hands you back a MASK you can wire into anything.

    It's the mask_io pair from swanjohn99/comfyUIcostumNodes - a small, new, single-author pack whose whole pitch is exact round-tripping.

    Why a saved mask is worth having

    Masks are the expensive part of a promptable-masking pipeline. In the current 2026 workflows - the LTX-2 inpaint setups, anything where you describe a region in words and let SAM 3 find it - the segmentation pass is the slow, memory-hungry step. Denoise, mask blur, grow, the prompt inside the region: none of that needs the segmenter re-run. Splitting the graph at the mask file is the cheap way to iterate.

    There's a fidelity argument too. A mask saved as a grayscale PNG is 8-bit, which is visibly stepped on a soft edge. A .pt keeps the original float32 values, pixel for pixel. If you're going to keep a mask around across sessions, keep the real thing.

    How it works

    The loader lists *.pt files in output/<subfolder>/ and turns that listing into the mask_file dropdown. On queue, it reads the file with torch.load(..., weights_only=True), unwraps it if it happens to be a dict containing a masks or mask key, checks that it really is a tensor, and normalizes the shape to ComfyUI's [B, H, W] convention - a flat [H, W] gets a batch dimension, [B, 1, H, W] or [B, H, W, 1] gets squeezed, anything stranger raises Unsupported MASK shape. Values are cast to float32 and handed over as-is.

    It also implements IS_CHANGED on the file's modification time, so re-saving over a mask re-triggers the graph instead of serving a cached result. Small thing; it's the difference between "works" and "why is it using the old mask".

    The inputs that matter

    • mask_file - the dropdown. It's built by scanning the subfolder at the moment your graph loads the node definition, and it shows (none) when the folder is empty. There's also a "select" button that opens a picker with sizes and timestamps, if you'd rather not squint at the dropdown.
    • subfolder - default masks. This must match what you typed in Save Mask Tensor, or the node will look in a directory that doesn't exist and error with the full path so you can see the mismatch.

    There's one output: masks (MASK, a float tensor [B, H, W]). Wire it wherever a mask goes - the inpaint conditioning nodes, a mask grow/blur pass, or a masked composite. Because it's the plain MASK type, nothing downstream needs to know it came from a file.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/swanjohn99/comfyUIcostumNodes
    

    Restart ComfyUI - that's the entire install. No pip packages, no checkpoints, no Triton (a relief if you've fought Triton to get a SAM 3 node running on Windows). It's published under the display name Mask Tensor I/O for the Comfy Registry, so try ComfyUI Manager for that name first; otherwise clone it.

    Both nodes come in the same clone, so you install once and get the saver too - plus a pair of Save/Load nodes for MiniMax H3 AV latents.

    Where people get burned

    The dropdown is a snapshot. Save a new mask while the node is already sitting in your graph and it will not appear in the list, because the choices were computed when the node was created. Refresh the node definitions (or reload the workflow) and it shows up. This trips up roughly everyone the first time.

    (none) is not a valid choice. Queue with it selected and you get a FileNotFoundError telling you to run Save Mask Tensor first - the pack assumes you're the one who made the files.

    The files aren't in input/. This loader reads from output/<subfolder>, not the input directory. Drop a .pt into ComfyUI/input/masks and the node will never see it. Same story if you point ComfyUI at a different output directory between sessions: from the node's point of view, the mask is gone.

    A deleted file stays in an old workflow. The name persists in the saved graph, so reopening a workflow after you cleaned out output/masks gives you a missing-file error rather than a fallback. Worth knowing before you go wild with the delete button.

    Batch dimension is preserved. If the saved mask was a ten-frame video mask, you get ten masks out. Feeding that into a single-image pipeline is on you - the node returns exactly what was on disk, which is the point, but the mask's batch size becomes part of your graph's contract.

    Categorymask_io

    Inputs (2)

    NameTypeDefaultDescription
    mask_fileCOMBO1 options: (none)
    subfolderSTRINGmasks

    Outputs (1)

    NameTypeDescription
    masksMASK