ComfyUI Node

Dynamic Universal Selector

Pick a model by regex, not by squinting at a dropdown

By inkbottle-9·Created 8 months ago·Updated 2 days ago· 1
Dynamic Universal Selector
    • first_matched
    • items_matched
    • matches_count
    categorysampler
    regex
    sort_modeascending
    search_allfalse
    refreshfalse

    The part of ComfyUI everyone resents is the dropdown. Your checkpoints folder has four hundred files with names like dreamshaperXL_v21TurboDPMSDE.safetensors and dreamshaperXL_v21TurboDPMSDE_fp16.safetensors, and every time you want a different one you scroll until your eyes cross. Dynamic Universal Selector is that problem turned into a query: it can see the same filename lists that populate every loader dropdown - plus the sampler and scheduler tables - filter them with a regex, and hand you the match as text you can actually wire somewhere.

    Why would you reach for it? Because of a ComfyUI quirk that trips up anyone who's tried to automate model choice: a loader's ckpt_name and lora_name ports aren't strings, they're combos - fixed dropdowns. Plug an ordinary text node into one and validation refuses the connection. This node sidesteps that by typing its outputs as * (the wildcard "accept anything" type), so its first match plugs straight into a Checkpoint Loader's name port, or into a KSampler widget you've converted to an input. That one trick is the whole point: it lets your graph decide which model or sampler to use, instead of you typing it.

    How it works

    At load time the node builds a catalog. Its category list is sampler, scheduler, plus every registered model folder from ComfyUI's folder_paths - checkpoints, LoRAs, VAEs, embeddings, controlnet, upscale models, the lot. Samplers and schedulers are read straight from core comfy.samplers.KSampler, so don't expect res_2m or friends from third-party packs like RES4LYF to show up in the sampler category - those live outside the stock table.

    When it executes, it filters the chosen category (or everything, with search_all) by your regex and returns the matches. Note the filter is a plain search, so xl matches anything containing "xl". To pin down one exact file - which matters because the loader will error on a name it can't find - anchor it: ^dreamshaper.*fp16\.safetensors$.

    The inputs and outputs that matter

    You'll touch maybe three settings:

    • category - narrows to one kind of item (sampler, scheduler, checkpoints, loras…).
    • regex - the filter. Empty means "match everything." Invalid regex raises an error on the node, so test it somewhere forgiving first.
    • sort_mode - ascending/descending order, or shuffling, which is the fun one.

    Three outputs come back: first_matched (a * string ready to feed a combo port), items_matched (the full list - wire it to a PreviewAny or an index node to pick by position), and matches_count (an INT if some downstream logic wants to know how many hit).

    shuffling deserves its moment. Each run it randomizes the list, so first_matched is a different model every time. Under the hood the node opts out of caching by returning a NaN fingerprint when shuffling is on - the same always-rerun trick every "random pick every run" node uses. Flip that on, feed first_matched into a Checkpoint Loader, and you have a roulette workflow that genuinely changes each generation. Otherwise it behaves lazily and only reruns when an input changes, which is the right default.

    Installing it

    It's one of seven utility nodes in the inkbottle-9/comfyui_dynamic pack, and it has no dependencies - pure stdlib. In ComfyUI Manager, search comfyui_dynamic, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/inkbottle-9/comfyui_dynamic.git
    

    Restart ComfyUI, and look under dynamic/utils. One catch that has quietly confused people: the pack is written against ComfyUI's newer V3 backend node API, so it needs a ComfyUI from roughly the second half of 2025 or later. If the node simply doesn't appear, that's the cause - update ComfyUI first.

    Gotchas

    The catalog is snapshotted at startup. Drop a new checkpoint in mid-session and it won't show until you tick refresh for one run (or restart). Leave refresh off day-to-day; it re-scans every single execution for no benefit. And when a regex is too loose, you won't get an error - you'll get the wrong model silently wired into the loader, which is arguably worse. Anchor your patterns, check matches_count, and keep sort_mode at a fixed order while you're debugging. It's a small node with one sharp edge, and it earns its place in a workflow the moment you have more models than patience.

    Categorydynamic/utils

    Inputs (5)

    NameTypeDefaultDescription
    categoryCOMBOsamplerAll the types, select one to narrow the search scope (when 'search_all' not enabled).
    regexSTRINGRegex to match the items you are interested in. Empty to match everything.
    sort_modeCOMBOascendingSorting order of items. You can use 'shuffling' to produce a random first item.
    search_allBOOLEANfalseSearch across all categories of items, ignoring 'category'.
    refreshBOOLEANfalseUpdate data before every execution. Not recommended to enable unless there is an explicit need for refreshing.

    Outputs (3)

    NameTypeDescription
    first_matched*Outputs the first string from the matching list.In certain scenarios, you can use strict-matching regex to ensure that the matched item is unique. This output is essentially a string, but its type is deliberately set to *, so you can connect it to any port that accepts COMBO, e.g. the name port of a Checkpoint Loader
    items_matched*Outputs a string list, you can link to 'PreviewAny' or some index node.
    matches_countINTLength of the matching list.