Validate Index
Your Semantic Search Index Is Rotting — This Node Tells You
- index
- index
- stale_count
- status
What it actually is
Validate Index is the housekeeping node for Eric's Semantic Search, the pack that turns a folder of photos into a searchable library using Qwen3-VL embeddings stored in a FAISS index. Build the index once, search it with natural language forever - that's the pitch. The "forever" is the part that needs maintenance, and this node is it.
The problem it solves is boring and real. You index a folder, then you do what people do with photo folders: you delete the outtakes, move things around, rename things. Nothing in the index notices. Your embeddings still point at files that no longer exist, and suddenly a great search result loads a blank image or throws an error. Validate Index finds those orphaned entries before they bite you.
How it works
Mechanically it's simple, and it's grounded in how the pack stores data. Every indexed file gets a row in a SQLite database plus a vector in a FAISS index. Validate walks every row in the DB and checks whether the file still exists on disk. Any entry pointing at a missing file is "stale." Turn on auto_clean and it removes those records in a batch, then sweeps up the orphaned thumbnails in the thumbnail cache.
One honest caveat: cleaning here is a soft delete. FAISS has no real deletion support, so the vectors linger in the index until you run the pack's Compact Index node, which rebuilds it and reclaims the space. Validate fixes your search results; Compact fixes your disk. If you've culled a lot of files, do both.
The inputs and outputs that matter
Only two inputs, and you'll mostly touch one:
index(SEMANTIC_INDEX, required) - the index you want to check.auto_clean(BOOLEAN, default False) - the interesting one. Set it to True to actually remove the stale entries.
Outputs: index passes the same index through so you can chain it into a workflow, stale_count gives you the number of dead entries as an INT, and status is a human-readable string - "Found 12 stale entries (set auto_clean=True to remove)" or "Cleaned 12 stale entries, removed 12 orphaned thumbnails."
The smart move: run it once with auto_clean off to see the count, then flip it on. You don't want a renamed folder to silently cull a chunk of your index - though actually, it can't. The node only ever removes entries for files that are gone. Nothing that still exists on disk is touched, ever.
Installing it
ComfyUI Manager: search "Semantic Search" (pack title "Eric"). Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/EricRollei/Semantic-Search
Then restart ComfyUI. The heavy part is dependencies: faiss-cpu, qwen-vl-utils, pillow-heif, plus the Qwen3-VL embedding model itself, which downloads automatically on first use. Budget roughly 20GB of disk for models and an 8GB+ GPU (16GB if you want the 8B variant). This is not a light pack - you're pulling a 2B or 8B vision-language model just to do the embedding.
Troubleshooting
Two gotchas from the README, both about the pack rather than this node specifically:
- Slow indexing: PyTorch 2.9.x has a known 3D-convolution performance regression that tanks throughput. Upgrade to 2.10+.
- CUDA OOM: drop
batch_sizeon Add Folder to Index, use the 2B model, or lowermax_resolution.
Validate itself is fast - checking whether files exist is cheap compared to embedding anything. If stale entries keep piling up, that's normal when you edit folders a lot; just make validating after a big cleanup a habit.
Should you reach for it?
If you're running the pack at all and your indexed folders change, yes - this is the "your data has gone stale" safety net. It's a thin node, but it's the kind of thin node that keeps a big pipeline honest. It's not the flashy part of semantic search; it's the part that makes sure the flashy part keeps working next month.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| index | SEMANTIC_INDEX | — | |
| auto_cleanopt | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| index | SEMANTIC_INDEX | — |
| stale_count | INT | — |
| status | STRING | — |