Any Match Router
Type a word, and the value takes that one of 64 paths
- any
- any_out_1
- any_out_2
- any_out_3
- any_out_4
- any_out_5
- any_out_6
- any_out_7
- any_out_8
- any_out_9
- any_out_10
- any_out_11
- any_out_12
- any_out_13
- any_out_14
- any_out_15
- any_out_16
- any_out_17
- any_out_18
- any_out_19
- any_out_20
- any_out_21
- any_out_22
- any_out_23
- any_out_24
- any_out_25
- any_out_26
- any_out_27
- any_out_28
- any_out_29
- any_out_30
- any_out_31
- any_out_32
- any_out_33
- any_out_34
- any_out_35
- any_out_36
- any_out_37
- any_out_38
- any_out_39
- any_out_40
- any_out_41
- any_out_42
- any_out_43
- any_out_44
- any_out_45
- any_out_46
- any_out_47
- any_out_48
- any_out_49
- any_out_50
- any_out_51
- any_out_52
- any_out_53
- any_out_54
- any_out_55
- any_out_56
- any_out_57
- any_out_58
- any_out_59
- any_out_60
- any_out_61
- any_out_62
- any_out_63
- any_out_64
ComfyUI has no switch statement - you get a wired graph, and every branch you build always runs. Any Match Router is the closest thing to switch (x) { case ... } in this pack: one input value, up to 64 outputs, and a match text box that decides which single output receives it. Everything else gets nothing.
How the routing actually works
The implementation is a short loop, and its three quirks are all visible in it:
result = [None] * self.MAX_OUTPUT_INDEX
for index in range(1, self.MAX_OUTPUT_INDEX + 1):
text = str(kwargs.get(f"text_{index}", ""))
if text and text == match:
result[index - 1] = any
break
return tuple(result)
Read that carefully, because it defines the node:
- It's plain string equality. Case-sensitive, whitespace-sensitive, whole-string. No substring matching, no regex, no wildcards and no fuzzy anything.
Catdoes not matchcat, and a trailing space you didn't see will make you think the node is broken. - An empty text field is skipped, and
matchis compared as-is. So an emptymatchmatches nothing at all - every output comes backNone. That's the single most common way to sit there wondering why nothing is flowing. - The first match wins and the loop breaks. Duplicate words across two text fields are a bug, not a shortcut: index 1 gets the value and the later twin gets nothing.
The node's declared inputs are any (required, wildcard - the value being routed) and match (STRING, the word you're testing against), plus the optional text_1 … text_64 fields that label the destinations. The outputs are any_out_1 … any_out_64. Backend-side, all 64 outputs are returned every run, mostly as None; the frontend hides the ones you haven't named.
The slots build themselves
This is where the schema and the screen disagree. The 64 text fields and 64 outputs aren't all on screen: a small frontend extension ships with the pack (web/js/dynamic_selectors.js) and maintains them as you type. Fill the last visible text field and the next one appears; an output socket is created only when its text field has something in it.
Two consequences worth internalizing. An output exists because you named it - delete the text in text_5 and any_out_5 vanishes, taking its wire with it, so save before you clear. And the socket labels are purely cosmetic: the visible output type mirrors whatever you plugged into any for readability, but the backend still treats it as wildcard.
If the node shows up with one output and no extra text fields, the extension didn't load - restart ComfyUI and hard-reload the browser tab (Ctrl+Shift+R). If you've turned on Nodes 2.0, know that the Vue frontend has been breaking third-party extensions for months; the standing workaround is to leave it off.
What you'd actually use it for
The killer feature isn't that it routes - a switch does that - it's that the router is driven by data. match is a normal STRING widget, so you can convert it to an input and let an upstream string decide the path: feed it a keyword, a label, a name that falls out of your own pipeline, and the graph reorganizes itself without you touching a wire.
Kept as a widget it's still useful: a variant selector, where you flip a word instead of rewiring. Against its packmates - Any Switch is A/B, Any If Else picks between two values, this one is dispatch.
One caveat, since the plumbing layer has a small culture war about this: routing any type into any socket is what earned the "please stop using the Anything Anywhere extension" backlash. Wildcard wiring makes a graph work and makes it harder to debug. Use it for dispatch you understand.
Installing it
MIT, brand new (first commits September 2026), and zero Python dependencies - empty dependency list, no requirements.txt, nothing to pip. It publishes to the ComfyUI registry automatically, so Manager sees it.
Manager → search ComfyUI Useful Stuff Nodes → Install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/ArtemKo7v/ComfyUI-UsefulStuffNodes
Restart ComfyUI, then reload the browser page - for this node that's not optional, because the dynamic slots are frontend work.
Where it goes wrong
All outputs None. Either match is empty, nothing matches its exact text, or the case/whitespace differs. The node can't tell you which, because it deliberately does nothing when there's no match. Copy the word straight out of the text field into match to rule out invisible characters.
Downstream nodes erroring. Same mechanism as any switch: the losing outputs carry None, the nodes behind them still execute, and anything expecting a real image or latent complains - usually naming the innocent node, not this one.
Missing node on a borrowed workflow. The JSON stores ArtemKo7vUsefulStuffNodesAnyMatchRouter; expect the red box until you install the pack.
Verdict: this is the one worth installing the pack for. It's a string-keyed dispatcher with no dependencies and no model downloads, and if you run workflows in several variants it removes a class of manual rewiring you'd otherwise be doing at 2am.
Inputs (66)
| Name | Type | Default | Description |
|---|---|---|---|
| any | * | — | |
| match | STRING | — | |
| text_1opt | STRING | — | |
| text_2opt | STRING | — | |
| text_3opt | STRING | — | |
| text_4opt | STRING | — | |
| text_5opt | STRING | — | |
| text_6opt | STRING | — | |
| text_7opt | STRING | — | |
| text_8opt | STRING | — | |
| text_9opt | STRING | — | |
| text_10opt | STRING | — | |
| text_11opt | STRING | — | |
| text_12opt | STRING | — | |
| text_13opt | STRING | — | |
| text_14opt | STRING | — | |
| text_15opt | STRING | — | |
| text_16opt | STRING | — | |
| text_17opt | STRING | — | |
| text_18opt | STRING | — | |
| text_19opt | STRING | — | |
| text_20opt | STRING | — | |
| text_21opt | STRING | — | |
| text_22opt | STRING | — | |
| text_23opt | STRING | — | |
| text_24opt | STRING | — | |
| text_25opt | STRING | — | |
| text_26opt | STRING | — | |
| text_27opt | STRING | — | |
| text_28opt | STRING | — | |
| text_29opt | STRING | — | |
| text_30opt | STRING | — | |
| text_31opt | STRING | — | |
| text_32opt | STRING | — | |
| text_33opt | STRING | — | |
| text_34opt | STRING | — | |
| text_35opt | STRING | — | |
| text_36opt | STRING | — | |
| text_37opt | STRING | — | |
| text_38opt | STRING | — | |
| text_39opt | STRING | — | |
| text_40opt | STRING | — | |
| text_41opt | STRING | — | |
| text_42opt | STRING | — | |
| text_43opt | STRING | — | |
| text_44opt | STRING | — | |
| text_45opt | STRING | — | |
| text_46opt | STRING | — | |
| text_47opt | STRING | — | |
| text_48opt | STRING | — | |
| text_49opt | STRING | — | |
| text_50opt | STRING | — | |
| text_51opt | STRING | — | |
| text_52opt | STRING | — | |
| text_53opt | STRING | — | |
| text_54opt | STRING | — | |
| text_55opt | STRING | — | |
| text_56opt | STRING | — | |
| text_57opt | STRING | — | |
| text_58opt | STRING | — | |
| text_59opt | STRING | — | |
| text_60opt | STRING | — | |
| text_61opt | STRING | — | |
| text_62opt | STRING | — | |
| text_63opt | STRING | — | |
| text_64opt | STRING | — |
Outputs (64)
| Name | Type | Description |
|---|---|---|
| any_out_1 | * | — |
| any_out_2 | * | — |
| any_out_3 | * | — |
| any_out_4 | * | — |
| any_out_5 | * | — |
| any_out_6 | * | — |
| any_out_7 | * | — |
| any_out_8 | * | — |
| any_out_9 | * | — |
| any_out_10 | * | — |
| any_out_11 | * | — |
| any_out_12 | * | — |
| any_out_13 | * | — |
| any_out_14 | * | — |
| any_out_15 | * | — |
| any_out_16 | * | — |
| any_out_17 | * | — |
| any_out_18 | * | — |
| any_out_19 | * | — |
| any_out_20 | * | — |
| any_out_21 | * | — |
| any_out_22 | * | — |
| any_out_23 | * | — |
| any_out_24 | * | — |
| any_out_25 | * | — |
| any_out_26 | * | — |
| any_out_27 | * | — |
| any_out_28 | * | — |
| any_out_29 | * | — |
| any_out_30 | * | — |
| any_out_31 | * | — |
| any_out_32 | * | — |
| any_out_33 | * | — |
| any_out_34 | * | — |
| any_out_35 | * | — |
| any_out_36 | * | — |
| any_out_37 | * | — |
| any_out_38 | * | — |
| any_out_39 | * | — |
| any_out_40 | * | — |
| any_out_41 | * | — |
| any_out_42 | * | — |
| any_out_43 | * | — |
| any_out_44 | * | — |
| any_out_45 | * | — |
| any_out_46 | * | — |
| any_out_47 | * | — |
| any_out_48 | * | — |
| any_out_49 | * | — |
| any_out_50 | * | — |
| any_out_51 | * | — |
| any_out_52 | * | — |
| any_out_53 | * | — |
| any_out_54 | * | — |
| any_out_55 | * | — |
| any_out_56 | * | — |
| any_out_57 | * | — |
| any_out_58 | * | — |
| any_out_59 | * | — |
| any_out_60 | * | — |
| any_out_61 | * | — |
| any_out_62 | * | — |
| any_out_63 | * | — |
| any_out_64 | * | — |