Negative Wildcard Processor
Inside the Negative Prompt
- text_positive
- text_negative
You've seen the problem if you've ever ported an old A1111 wildcard pack into ComfyUI. The dynamic-prompt syntax { rain, umbrella | sunshine, sunglasses } lets each alternative bundle its own little negative - the thing to avoid for that option. ComfyUI's wildcard nodes happily expand {a|b} and dump everything, including the avoid-words, into the positive prompt, where they get treated as positive attention. That's backwards: you're actively asking the model to draw the thing you wanted to suppress.
Negative Wildcard Processor is the fix. It's a plain text-splitting node that strips text wrapped in <! !> out of your positive prompt and appends it to your negative. The README example is the whole idea in one line:
{ rain, <!umbrella,!> | sunshine, <!sunglasses,!> }
Expanded, the positive gets "rain, " and the negative picks up "umbrella," - so every alternative in your wildcard carries its own anti-prompt without polluting the positive stream.
How it works
Under the hood it's two regexes and nothing else. It finds everything matching <! ... !>, removes it from the positive string, and tacks each match onto the end of your negative. It also strips <lora ...> tags from the positive output on its way through, which quietly saves you from wildcard packs that embed lora syntax leaking into the CLIP encoder. No models, no dependencies beyond Python's standard library, no GPU involved - this node never sees a tensor.
One honest caveat, because it matters more than the node itself: negatives only do anything on models that actually use them. On guidance-distilled models running at CFG 1 (most turbo/lightning variants, Z-Image Turbo) the negative prompt is inert by design - there's no unconditional pass to steer. This node is for SDXL, SD 1.5, Pony/Illustrious derivatives at CFG 3+, and de-distilled Flux workflows, where negatives genuinely shape the output.
The inputs that matter
Just two, both STRING with forceInput (so wire them, or type directly):
- positive - the wildcard-expanded prompt, typically straight from a Dynamic Prompts or
{a|b}-style wildcard node. - negative - your baseline negative. The extracted bits get appended to the end of it.
It returns two strings: text_positive and text_negative. They wire straight into CLIP Text Encode (Positive) and CLIP Text Encode (Negative) respectively. The beginner move that bites: wiring both outputs into the same encoder. Each output has exactly one job.
Install
It's in the ComfyUI Manager registry, so the easy path is Manager → search "Negative Wildcard Processor" → install → restart. Or clone it:
cd ComfyUI/custom_nodes
git clone https://github.com/GrvBdgr/comfyui-negativewildcardsprocessor
Then restart ComfyUI. That's the whole install - the pack ships no requirements.txt and downloads no models, which in this ecosystem is practically a luxury. It shows up under the Dynamic Prompts category.
Gotchas
- The delimiter is hardcoded
<!and!>. The match is non-greedy, so content stops at the first!>- don't nest them. - If your wildcard isn't being split, check the obvious one: the pattern has to be literally
<!content!>with no spaces between the markers and the brackets. - On a distilled model, "nothing happened" is the expected result - that's the model, not the node. Blame CFG 1, then go state constraints positively instead.
It's a small tool and it does one thing, but it's the difference between wildcard packs that feel broken and packs that just work.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | STRING | — | |
| negative | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text_positive | STRING | — |
| text_negative | STRING | — |