JSON Extract
Turn an LLM's JSON blob into graph wires
- found
- report
- value_1
- value_2
- value_3
- value_4
- value_5
- value_6
- value_7
- value_8
- value_9
- value_10
- value_11
- value_12
The moment you put a local LLM in your graph, you discover its dirty secret: it doesn't reliably hand you clean data. Even with structured-output constraints, you get a JSON blob wrapped in a sentence, or a deeply nested object when you wanted one field. JSON Extract is the bridge - it pulls the fields you name out of a JSON string and puts each one on its own STRING output, ready to wire into a prompt, a filename, or another node. It's the "extract the data from the LLM" step in the pack's LLM-in-the-graph story, and it's patient about the mess: the tooltip says prose around the JSON is tolerated - the first {…} or […] is parsed and the rest is ignored.
The key input is paths, and its format is the whole ergonomics story. It's one path per line, either a bare path or path -> alias:
style_description.lighting -> lighting
elements[*].desc
characters.0.name
Blank lines and # comments are ignored, [*] / * wildcards grab every element of an array (joined with array_join, default ", "), and each line grows one auto-labelled value_* output - named by your alias, or the path's last key. So the graph is self-documenting: value_1 isn't a mystery, it's labelled lighting. Outputs are rebuilt when you click away from the field, not while you type, so they appear complete and ready to wire. There's also a 🔍 Explore JSON button - paste a sample (or reuse the node's last run) and click + on any field to add its path, which is how you avoid typing dot-paths by hand. default is the value returned for a path that isn't found (and for every output if the whole JSON can't be parsed), which is your safety net against a model that changed its output shape mid-run.
Outputs: found (a boolean - did the parse succeed at all), report (what got pulled and what didn't), and value_1 … value_12 (one per path line, in order).
Installing
Ships in Kinburg-Nodes: ComfyUI Manager → search "Kinburg-Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Kinburg/Kinburg-Nodes
# restart ComfyUI
Pure Python - no extra dependencies. It lives in the pack's util package, so it doesn't require the LLM infrastructure to use; it's just where you send an LLM's output.
Gotchas
The two things that catch people: outputs rebuild on blur (click away from the paths field), and default quietly masks missing fields. If you're debugging why a value looks wrong, check found first - false means the JSON itself didn't parse, and every output is falling back to default. And remember paths are dot-notation over a parsed object, not JSONPath - elements[*].desc is the supported wildcard form, and an array index is characters.0.name. The Explore JSON button is genuinely the fastest way to get these right.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| json_string | STRING | The JSON to read — wire an LLM JSON output here, or type/paste. Prose around the JSON is tolerated (first {…}/[…] is parsed). | |
| pathsopt | STRING | # one path per line — `path` or `path -> alias` # e.g. style_description.lighting -> lighting | One path per line — `path` or `path -> alias`. Blank lines and `# comments` are ignored. Each line makes a labelled value_* output; the outputs are rebuilt when you click away from this field. Use 🔍 Explore JSON to click fields out of the last run. |
| defaultopt | STRING | Value returned for a path that isn't found (and for every output if the JSON can't be parsed). | |
| array_joinopt | STRING | , | Separator used to join matches when a path uses a `[*]`/`*` wildcard (e.g. elements[*].desc). |
Outputs (14)
| Name | Type | Description |
|---|---|---|
| found | BOOLEAN | — |
| report | STRING | — |
| value_1 | STRING | — |
| value_2 | STRING | — |
| value_3 | STRING | — |
| value_4 | STRING | — |
| value_5 | STRING | — |
| value_6 | STRING | — |
| value_7 | STRING | — |
| value_8 | STRING | — |
| value_9 | STRING | — |
| value_10 | STRING | — |
| value_11 | STRING | — |
| value_12 | STRING | — |