Skip to content

Reading JSON

A JSON document carries many values; a node usually needs one. Extract JSON Value (utility/extract) reads one value from a document with a path and hands it on with its own type — the customer’s name as text, the VIP flag as a boolean, the score as a number, the list of lines as JSON — so that the next node receives exactly what it expects.

Source Node and port
A document the caller sends: an order, a record, a plan JSON Value Input (input/json_value) → json
An AI model asked for JSON Text Generation (ai/text_generation) with Response Format JSON Object → json, and the other AI nodes with a JSON output
A collection built from a list Aggregate JSON (aggregate/json) → result
A document checked against a schema Validate JSON Schema (utility/json_schema_validate) → its validated output
A text that holds JSON: a model’s answer, a JSON field of a CSV row, a webhook body Parse JSON (utility/json_parse) → json

A document is read the same way whether it travels inline or as a stored file.

A text that contains JSON is not a JSON value: text does not connect to a json port, and the validator says so. Put Parse JSON (utility/json_parse) between them. It reads the text the way a model writes it — a quoted string, one ```json fence around the object — and with Find first it takes the JSON inside a longer answer (“Here is the map you asked for: {…} Let me know…”). A text that is not JSON stops the step with the line and position where it breaks; in mode route it is sent to a correction branch instead, through valid and errors, and the steps that read json are skipped. Parse JSON can also check the result against a schema, chosen as in Validate JSON Schema: a Madoo contract such as madoo.keyframe-map/v1, a schema written in the node, or one received on its input — one node for “read this text as JSON and make sure it is the right JSON”. When the AI node has a JSON mode (Response Format JSON Object), its json output is already parsed and needs no Parse JSON. The hotel offer lab reads a model’s answer this way and builds a listing from it.

A path walks from the top of the document to the value:

Path Reads
customer.name the name field of the customer object
lines[1].sku the sku of the second line (indexes start at 0)
lines the whole list, as JSON
[0].sku the sku of the first item, when the document itself is an array
$.customer.name the same as customer.name: a leading $ is accepted

Fields are separated by ., array items are chosen with [n]. There are no wildcards and no filters: one path, one value. A field whose name contains a dot or starts with [ cannot be addressed. To work on every item of a list, iterate over it (enumerate/json, see Iteration); to add up or count the items, use Calculate, whose paths accept [*] (sum(order.lines[*].qty)).

Expected Type says what the value must be: text, number, boolean, json (an object or an array), or auto (whatever it is). The value is never converted: when it has another type, the node fails with EXTRACT_TYPE_MISMATCH and a message that names the path, the type found and the type expected.

Set it whenever you know the type. An AI model that answers "true" instead of true, or "85" instead of 85, is then caught at the step that reads the value, with a clear message — not three nodes later, where a comparison fails for no visible reason, or never, where a text is printed in place of a number. With auto the output takes the type of the value it finds, which is useful only when several types are legitimately possible.

When Missing decides what happens when the path leads nowhere — the field is not in the document, or the array is shorter than the index:

When Missing The node value found
fail (default) fails with JSON_PATH_NOT_FOUND — —
absent completes absent: the nodes that need it are skipped false
default completes Default Value, which must have the expected type false

Choose by what a missing field means for the result:

  • fail when the field must be there: an order without a customer is a broken order, and the run should say so.
  • absent when the field is optional and the branch that uses it should simply not happen: no coupon code, no coupon line on the invoice.
  • default when a missing field has an obvious value: no shipping method means "standard".

Found is true when the path led to a value, false when absent or default was used. It is a boolean, ready for a decision: if the order carries a coupon, then…

A field that is present with the value null is found: found is true and the value is JSON null. Missing and null are different things in JSON, and Extract keeps them apart.

The values and JSON lab receives an order, a boolean and a number, and reads six values from the order — one per way of reading:

The lab: an Order JSON input and two scalar inputs; six Extract nodes read the customer name, the VIP flag, the second SKU, all lines, a coupon code that is missing and a shipping method with a default; each output shows the value of the reference run

The order it receives (the coupon and the shipping method are deliberately missing):

{ "customer": { "name": "Giulia Ferri", "vip": true },
"lines": [ { "sku": "LMP-04", "name": "Table lamp", "qty": 2, "price": 89.0 },
{ "sku": "CHR-11", "name": "Oak chair", "qty": 1, "price": 240.0 } ] }
Extract Path Expected When Missing Result
Customer name customer.name text fail "Giulia Ferri"
VIP customer customer.vip boolean fail true
Second line SKU lines[1].sku text fail "CHR-11"
All lines lines json fail the two lines
Coupon code coupon.code text absent absent, found = false
Shipping method shipping.method text default "standard" "standard", found = false

The run takes about five seconds and costs nothing. Send "vip": "yes" and the VIP step fails with Value at 'customer.vip' is 'text', not the expected 'boolean'. — the rest of the run completes, and the run ends as partial success.

Install it into your workspace with an API key (Node 18 or later, no dependencies):

Terminal window
node madoo-install-example.mjs lab-values --api <your Madoo API URL> --key <key.json> --run

The installer is at /downloads/madoo-install-example.mjs; installing costs nothing, and --run runs the lab once and prints each output.

Code Cause Fix
EXTRACT_TYPE_MISMATCH the value has another type than Expected Type fix the producer (an AI prompt that asks for true, not "true"), or accept the actual type
JSON_PATH_NOT_FOUND the path leads nowhere and When Missing is fail check the path against a real document; use absent or default if the field is optional
INVALID_JSON_PATH the path is malformed: an empty segment, an unclosed [, a negative index write it as a.b[0].c
DEFAULT_TYPE_MISMATCH Default Value does not have the expected type give a default of the expected type ("standard" for text, 0 for a number)
MISSING_JSON_INPUT nothing reached the json port, or a file that is not JSON did connect a JSON output
INVALID_JSON_INPUT the document is not valid JSON fix the producer