filter empty
Cleaning a LIST Without Blowing Up Your Batch
- list
- list
Search for filter empty in ComfyUI and you get two nodes with exactly the same name in two different categories. This one, in Basic/LIST, is the version for Python lists held in a single variable - and it's the one you want when you're tidying data before it becomes a batch, not after.
Getting the two mixed up is the most common way to waste twenty minutes on this node, so let's start with what makes it different.
LIST is one value, not a queue
ComfyUI's collection types behave differently in ways that are invisible until something goes wrong. A LIST here is an ordinary Python list passed down a single wire as one object: downstream nodes see one value, the whole collection, and run once. Nothing iterates. That's the opposite of the native data list, where the socket is a fan-out point and every item spawns a run - the distinction our knowledge base's node-plumbing map calls out as the fundamental one in this layer of the graph.
So why filter a LIST? Because blanks are a plague in any list built from text, and they follow you downstream. Split a prompt file and you get a trailing "". Split "cinematic, , moody" on commas and you get " ". Read a CSV column that was empty and you get None. You want those gone before you sort, index into them, or hand the whole thing over to generate forty images - sorting with a blank in it puts the blank at index zero, which is precisely the index you reach for first.
Mechanism
ListFilterEmpty is a single comprehension over the list, using the pack's shared emptiness test. Nothing else in ComfyUI is invoked, and the pack has zero install dependencies - its pyproject.toml declares dependencies = [], and that's the truth of it, not README optimism.
Emptiness means: None, "", or anything of length zero ([], {}, set()). Emptiness does not mean falsy. 0, 0.0 and False all survive, on purpose - the pack's own tests assert exactly that. So this is not a generic "remove falsy junk" filter; it keeps your legitimate zeros.
A None input is handled gracefully too: you get an empty list back rather than an exception. That matters when the upstream node is a conditional branch that didn't fire.
Inputs and output
list is the required input, typed LIST. The optional treat_whitespace_as_empty boolean is off by default and is the only choice you actually make here. Turn it on and a string consisting only of spaces, tabs or line breaks counts as empty and gets removed. Turn it off and " " stays, which is usually not what a human means by "empty" but is the safe default if you care about string content.
One output named list, a new LIST. The original is untouched.
Because the output is a single value, how it continues is your call: index into it with the pack's get item / first / last, sort or reverse it, or convert it to a data list (convert to data list) when you finally want each surviving entry to drive its own queue item. That last hop is the pattern to internalise - clean the collection as a LIST, then hand it over for iteration.
Installing
ComfyUI Manager, search Basic data handling, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/StableLlama/ComfyUI-basic_data_handling
# restart ComfyUI
No models, no pip packages, no build step. The node appears under Basic/LIST as filter empty.
Two things about the pack itself. Version 2.2.0 introduced both filter-empty nodes, so an older clone won't have this one - update rather than troubleshoot. And the author is genuinely around: StableLlama turns up in r/comfyui help threads answering questions about their own nodes. For a small utility pack that beats a changelog, because ambiguity gets an answer instead of a void.
Common issues
You grabbed the wrong twin. If the thing you're filtering is a batch that fans out into one run per item, you're in the wrong article - you want Basic data handling: DataListFilterEmpty from Basic/Data List. The display names are identical, so the category in the node title bar is the only tell.
Whitespace survived. Default is off; the " " entries from a comma split are still there. Flip treat_whitespace_as_empty on and expand the node, because the boolean will be hidden by default width.
Everything vanished. Filter a list where every entry was blank and you get an empty LIST, which flows downstream happily and produces nothing usable. Drop a length node after the filter while you're building.
You expected a data list out. You get a LIST. Iteration needs an explicit conversion step; a LIST output does not create runs on its own.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| list | LIST | The LIST whose empty entries are removed. | |
| treat_whitespace_as_emptyopt | BOOLEAN | false | When enabled, STRINGs that consist only of whitespace (spaces, tabs, line breaks) are removed as well. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| list | LIST | A new LIST without the empty entries. |