Get Key From JSON by Index
The boring node that stops your workflow being random
- json_input
- ui_widget
- string
Most "random picker" nodes in the wild are exactly what you don't want when you're testing: they sample, so every run is a different experiment and you can't compare anything. LF_GetKeyFromJSONByIndex does the unglamorous opposite. Give it a JSON object and a number, get the key at that position. Run it fifty times with index 3 and you get the same thing fifty times.
That's the whole node. It's plumbing in the most literal sense - nothing in it touches pixels - and it's the piece that makes a sweep sweep instead of scatter.
How it works
The mechanism is Python dict insertion order, which is guaranteed since 3.7 and is also the order json.loads preserves from your file. Index 0 is the first key in the document, index 1 the second, and so on. Values are irrelevant; the node only ever looks at keys.
That gives you the property the pack's own docs call out: this distinguishes insertion order from alphabetical order. Their worked example is {"Zebra":"", "Alpha":"", "Middle":""} - index 1 returns Alpha from a file whose keys read Zebra-first. If you've ever written a wildcard file and assumed it'd come back sorted, this is the node that will prove you wrong in a way you can act on.
Practically, that makes it a counter. Pair it with something that increments - or with the pack's primitive nodes carrying history - and an index walks through a list of artist names, LoRA filenames, checkpoint keys or region IDs in a defined sequence. Index-based selection is also the honest way to do an XY-style sweep: vary one index across runs and you know exactly which line in the config produced each image, because the receipt is the index.
The inputs and outputs that matter
Two required inputs, which is the whole interface:
json_input- the object whose keys you want. Empty objects are rejected with a clear error rather than returning nothing.index- zero-based, default 0. It does not wrap. Ask for index 9 in a five-key object and you get an error naming the valid range, not a silent wraparound to key 4. That's the right call for sweeps: a wrap would quietly give you a duplicate datapoint.
There's also an optional ui_widget - the pack's code widget - that displays the selected key in the node. Handy when you're eyeballing a long run and want to see what it picked without opening the output.
The single output is string: the key's name. Wire it into a filename prefix, a prompt fragment, a LoRA-name input, a switch selector - anywhere a string goes.
How to install it
ComfyUI Manager → search LF Nodes → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/lucafoscili/lf-nodes
python -m pip install -r lf-nodes/requirements.txt
Use ComfyUI's interpreter for pip, not a stray system Python. This particular node is dependency-free Python - but it ships inside a 154-node suite whose requirements include torch, transformers and rembg, so the install itself is not trivial. And note the vintage: the author archived lucafoscili/comfyui-lf in October 2025 and moved everything to lf-nodes; posts linking the old URL are out of date.
Common issues & troubleshooting
"Index N is out of range for M keys." Not a crash to fear - it's the node telling you the count. Useful when a config file silently lost a line and your sweep now has one fewer datapoint than you planned.
The key you got isn't the one you expected. You expected alphabetical order. It's insertion order. Reorder the JSON if you want a specific sequence - the file's order is the API here.
It refuses your JSON. The input has to be a non-empty object with string keys. A JSON array isn't an object; a list of one dict is unwrapped automatically, but a bare array with two dicts in it errors, deliberately - there's no unambiguous index into that.
Is there a random version? Yes, the pack has a seeded random-key selection node too. If your goal is a fair sample of the whole file over many runs, use that. If your goal is "cover every entry in order, no repeats, no gaps", use this one with an index you control.
Nothing shows in the widget. The optional code widget only mirrors the selection for display; the actual output is on the string socket and works headless. Check whether the node was muted before you debug anything else.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| json_input | JSON | Object whose keys are read in insertion order. | |
| index | INT | 00–18446744073709550000 | Zero-based key position: 0 selects the first key. Does not wrap. |
| ui_widgetopt | LF_CODE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| string | STRING | Key at the requested zero-based position in JSON insertion order. |