ICHIS Tag File Loader
Turn a tag CSV into something the graph can actually query
- metadata
- categories
- all_tags
- resolved_path
- cache_hit
The Ichis tag pipeline - Loader → Category Select → Sampler → Save - is only as good as its data source, and this node is the data source. You point it at a CSV or JSON file of tags organized into categories, and it parses the file once, caches the result, and hands every downstream ICHIS node a structured ICHIS_TAG_METADATA payload they can actually query. Without it, the whole family is just text utilities.
What file formats it eats
The loader is deliberately forgiving about CSV layout. From the pack's own sample data, it accepts:
- Row-per-tag:
image,category,tag- one tag per row, category in its own column. - Row-per-category-list:
category,tags- one row per category, with the tags column split on commas (and;,|, or tabs normalized to commas). - Tag-only: just a list of tags, which all land under an
uncategorizedbucket.
JSON is simpler: an array of objects like {"category": "faces", "tags": ["smile", "blue eyes"]}, where tags can be a list or a string. Category matching is case-insensitive by default (ignore_case), so Faces and faces resolve to the same bucket.
How the caching works
The loader caches parsed metadata keyed by (resolved_path, ignore_case) and checks the file's mtime, so editing the file between runs is detected and re-parsed. If you want to force a reload regardless, flip refresh - it bypasses the cache. cache_hit on the outputs tells you whether this run re-read the file or reused the cached copy, which is a genuinely useful diagnostic when the graph isn't showing what you expect.
One more subtle thing: the loader broadcasts the parsed categories over a ComfyUI PromptServer event (ichis-tag-loader). That's what lets the Category Select node's dropdowns update live in the browser without reloading the graph - the front-end half of the pipeline is driven from this node's output.
The inputs and outputs that matter
file_path- required. Absolute path, or relative tobase_dirif you set one.~and env vars are expanded.ignore_case- default on; keep it on unless your categories are genuinely case-distinct.refresh- force re-read past the cache.debug- prints what columns it detected and what it resolved.
Outputs: metadata (the ICHIS_TAG_METADATA payload), categories (LIST), all_tags (LIST), resolved_path (STRING), and cache_hit (BOOLEAN).
Gotchas
The big one: metadata is a custom type that only other ICHIS nodes know how to read. It's the backbone of this pack's pipeline, not a general-purpose data format. Also, a missing file does not error - it returns empty metadata with an error note inside the payload and cache_hit = False. If your dropdowns come up empty downstream, check resolved_path first; the loader will happily resolve a path that doesn't exist and stay quiet about it unless debug is on.
Installing it
It's part of the Ichis pack:
cd ComfyUI/custom_nodes
git clone https://github.com/ichabodcole/ComfyUI-Ichis-Pack
Restart ComfyUI, or install ComfyUI-Ichis-Pack via ComfyUI Manager. Pure Python stdlib parsing - no model downloads, no extra dependencies.
Where it fits
Run it once with a category CSV you maintain by hand, then wire metadata into ICHIS Tag Category Select and let the Sampler do the randomized drawing. It's the file-backed foundation that turns "random tags" from a coin flip into "random tags drawn from a curated, categorized catalog."
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| file_path | STRING | — | |
| base_diropt | STRING | — | |
| ignore_caseopt | BOOLEAN | true | — |
| refreshopt | BOOLEAN | false | — |
| debugopt | BOOLEAN | false | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| metadata | ICHIS_TAG_METADATA | — |
| categories | LIST | — |
| all_tags | LIST | — |
| resolved_path | STRING | — |
| cache_hit | BOOLEAN | — |