Smart Model Path Finder (Deep Subfolder Locator)
The node that tells you where your models actually live
- full_path
- relative_path
- found
- match_info
You downloaded the checkpoint. You know it's on disk. ComfyUI still shows a red loader widget and a value not in list error, because the file lives in models/checkpoints/sdxl/ and the workflow asked for mymodel.safetensors - or the other way round. That's how shared workflows die on other people's machines, and it's the thing this pack exists to kill.
The pack's headline feature is automatic: it hooks ComfyUI's own path resolution and silently fixes red widgets. Smart Model Path Finder is the manual half - a node that takes a filename, searches your whole models/ tree, and hands back the real path plus a flag for whether it found anything and how.
How it works
The pack builds one shared index (SmartModelIndex) of your models directory. On startup a background thread walks every folder registered in folder_paths.folder_names_and_paths - including anything you added via extra_model_paths.yaml - and records each file, filtered to real model extensions (.safetensors, .ckpt, .pt, .pth, .bin, .sft, .onnx, .gguf). Two maps come out: category → relative paths, and lowercased basename → every (category, path) that has it. The scan is cached for 120 seconds.
When the node runs, model_name goes through find_model, which does an exact basename match - category first, then across every other category. That's the subfolder fix: you ask for marigold_v2_normals.safetensors, and it doesn't care that the file is three folders deep or sitting in a different category entirely.
If nothing matches exactly and allow_fuzzy is on, it falls through to token-aware similarity scoring. This is the part the author actually thought about: the scorer strips revision noise - int8, fp8, pruned, convrot, bf16 and friends - then scores on model family (flux, qwen, wan, ltx…), parameter size, and shared content tokens. So a file you don't have surfaces as an 89% match for the pruned revision you do, instead of some random file that happens to share a substring.
The inputs and outputs that matter
Three inputs, all straightforward:
model_name- the filename you're hunting for. Bare name orfolder/file.safetensors, both work. The default value is the author's placeholder (marigold_v2_normals.safetensors, a depth model); just type yours over it.category- a dropdown:ALL, plus every model category your install reports. Set this to the real category when you know it. See the trap below.allow_fuzzy- on by default. Turn it off if you want only exact hits, no guesses.
Four outputs: full_path (the absolute path on disk), relative_path (the string you'd paste into a loader widget), found, and match_info - the useful one, because it tells you how it matched: something like Found via exact_category_subfolder, Found in loras via cross_category_loras, Found similar candidate (89% match): …, or a clear not-found message.
Both path outputs are strings, so they wire into anything that takes a path - a save prefix, a text node, a converted loader input. But be honest about the workflow: in practice you run the Finder once, read match_info, paste relative_path into your loader, and delete the node. It's a diagnostic, not a pipeline component - and only gate on found after reading the caveat below.
The traps, and there are two real ones
ALL is not all. ALL first tries checkpoints, then falls through a hardcoded list: diffusion_models, loras, vae, text_encoders, checkpoints, controlnet, upscale_models. A file in clip_vision, embeddings, or anywhere else gets walked straight past - and the fuzzy fallback under ALL only searches diffusion_models too. Set the category explicitly and this whole "but it's right there" class of failure disappears.
found can be True on a fuzzy hit. A 60% similarity guess sets found=True and puts the percentage in match_info. If you wire found into logic that assumes an exact match, you'll get a plausible-looking wrong file. Check match_info - or set allow_fuzzy off whenever anything downstream depends on the answer.
How to install it
No pip dependencies at all - the pack is standard library plus ComfyUI's own APIs. Search "ComfyUI-SmartModelResolver" in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/tahakhorsand/ComfyUI-SmartModelResolver
then restart ComfyUI. Nothing to download. Small single-author pack (Taha Khorsand, GPL-3.0); the node is written against the newer Nodes 2.0 authoring API with a legacy fallback, so it loads on old and new frontends alike.
Common issues & troubleshooting
It can't find a file you just added. The index caches for 120 seconds. Restart ComfyUI, or hit the pack's cache-refresh button (it forces a rescan), then re-run the node.
found is false and full_path is empty. Check the extension first - .py, .json and anything off the whitelist are deliberately ignored. Then check the file sits inside a folder ComfyUI knows about: the scanner walks registered directories only.
You fixed it, ran the workflow, and something else broke. This pack doesn't just add a node - on import it patches folder_paths.get_full_path, folder_paths.get_filename_list, and ComfyUI's prompt validation, install-wide. That's what makes the automatic red-widget fix work, and it applies to every node in your graph. Usually invisible, but it does mean a mistyped model name can resolve to a same-named file somewhere else instead of failing loudly. If you're debugging "why did it load that?", disable the pack and restart to get vanilla resolution back.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| model_name | STRING | marigold_v2_normals.safetensors | Model filename to find (e.g. model.safetensors or folder/model.safetensors) |
| category | COMBO | ALL | Target model category directory or 'ALL' to search across categories |
| allow_fuzzy | BOOLEAN | true | Allow fuzzy semantic matching if exact filename is not found |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| full_path | STRING | — |
| relative_path | STRING | — |
| found | BOOLEAN | — |
| match_info | STRING | — |