Filter Colors
Two dresses, two colours, one very confused model
- processed_text
- filtered_tags
red dress, blue dress is not a description of anything. It's what happens when your prompt got assembled rather than written: an LLM wrote three variations of the same outfit, a {red|blue} group got expanded twice, you merged two prompt fragments, or a Pony-style tag soup came out of a tagger. The model has no idea which one you meant, so it does the reasonable thing with two contradictory tags - blends them. You get a muddled in-between colour, or two dresses, or a dress that changes colour across the seam.
Filter Colors fixes that one class of mess: within a prompt, keep the first colour mentioned for each thing, drop the rest. It's boring, it's tiny, and it quietly removes a whole category of "why does the output look confused" from tag-based workflows.
What counts as a colour
The list isn't invented by the node. It reads the color key of the pack's own resources/wildcards.yaml - the same twenty-six values FilterTags expands <color> from: aqua, beige, black, blue, light blue, dark blue, brown, dark brown, green, dark green, light green, grey, lavender, maroon, orange, pink, purple, dark purple, light purple, red, silver, white, yellow, gradient, two-tone.
Matching sorts the list longest-first, so light blue dress is read as its own colour rather than a blue thing that happens to be light. And what follows the colour is treated as the thing: everything after it, to the end of the tag. That's the whole trick, and it produces sensible behaviour - black hair, black dress, blue eyes is three things and all three stay. Only a repeat of the same thing loses its colour: red dress, blue dress keeps red, and white shirt, black shirt keeps white.
First mention wins, which means order is your lever. With {red|blue|green} dress upstream, whichever spelling lands first in the string is the one that survives.
The inputs and outputs
text is a socket, not a text box - you can't type into this node, you wire a prompt into it from whatever produced it (the pack's TextPrompt, a string primitive, another prompt node).
Two outputs. processed_text is your prompt with the losing colours gone, and it goes into your positive CLIP Text Encode. filtered_tags is a comma-joined string of what was dropped - genuinely useful for debugging, because the usual failure is "it didn't fire and I don't know why". Park it on a preview or note node and you can see exactly what it decided.
The removal preserves whitespace and line breaks, so a multi-line prompt doesn't collapse into one unreadable line every time something gets dropped. And BREAK doesn't hide anything from it: the node treats BREAK-separated groups as one picture, so red dress BREAK blue dress still loses the second dress. Which is right, since the conditioning is describing one image.
Installing it
ComfyUI Manager → search ComfyUI-Alchemine-Pack → install → restart. Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/alchemine/comfyui-alchemine-pack
cd comfyui-alchemine-pack && pip install -r requirements.txt
requirements.txt is a single dependency (python-dotenv), nothing downloads models, and the nodes show up under AlcheminePack/Prompt in the add-node menu. That's the entire setup - no .env needed for prompt nodes.
If you're already running the pack's ProcessTags chain, this step is inside it: filter_colors is on by default there, sitting between subtag filtering and SDXLAutoBreak. Finding the same two-tag input suddenly collapsing is usually that checkbox. (If you saved a workflow on a version before 6.0.0, re-check those widgets - the pack inserted filter_colors and filter_plurals into ProcessTags and shifted the ones after them.)
Where it stops working
- A bare colour is never touched. The pattern needs a colour plus something after it, so
red, bluestays exactly as it is. It filters colours of things, not colour tags. - Only the listed colours count.
crimson dress, red dresssurvives intact. The fix is to editresources/wildcards.yamland add the values you actually use - that file feedsFilterTags'<color>wildcard too, so one edit improves both nodes. - Weights don't hide anything. Matching happens with the weight notation stripped, so
(red dress:1.2)is recognised and the surviving tag keeps its weight. - It won't deduplicate anything else. Repeat a colour, get it removed. Repeat a tag with no colour in it, or repeat a colour for two different things, and the node correctly does nothing - that's
FilterSubtags' job.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| processed_text | STRING | — |
| filtered_tags | STRING | — |