Set (core.set)
Build or patch each item's JSON: add fields, overwrite fields, or reshape the item to exactly the fields you name. One output item per input item, in order.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | merge | keep_only | merge | merge patches your fields into the item's existing JSON. keep_only replaces the item's JSON with exactly your fields. |
fields | list of {name, value} | [] | The fields to write. Both name and value accept {{ }} expressions, evaluated per item. |
Behavior
merge (default) — keeps everything already on the item and writes your
fields over it:
input {"a": 1, "b": "original"}
fields b = "patched", c = "new"
output {"a": 1, "b": "patched", "c": "new"}
keep_only — the output item contains only your fields (use it to trim
noisy API responses down to what downstream nodes need):
input {"a": 1, "noise": true, "more": [1, 2]}
fields kept = {{ $json.a }}
output {"kept": 1}
Expressions keep their type. A value that is a single whole expression returns the native value — numbers stay numbers, objects stay objects:
value "{{ $json.count }}" → 7 (number)
value "{{ $json.address }}" → {…} (object)
value "total: {{ $json.count }}" → "total: 7" (mixed text interpolates as a string)
Non-string literal values (real numbers, booleans, objects, null) pass
through untouched.
Per-item evaluation. Expressions run once per input item, so
{{ $json.n * 2 }} doubles each item's own n.
Dynamic field names. name accepts expressions too:
name = {{ $json.column }} writes under whatever key that item carries.
Binary passes through in both modes — attachments on the input item stay on the output item, untouched.
Quirks & tips
- No dot-path nesting (differs from n8n).
name = "a.b"writes the literal key"a.b"— it does not create{"a": {"b": …}}. To build nested structure, set the whole object:value = {{ {"b": $json.x} }}undername = "a". - A missing reference stops the node.
{{ $json.nope }}on an item withoutnopefails the run with an error naming this node — it does not silently writenull. Guard with the IF/Filter nodes upstream if a field is genuinely optional. - Duplicate names: last one wins. Two rows named
x→ the lower row's value is what lands. - Setting a value to
nullkeeps the key ({"a": null}), it does not delete it. To drop keys, switch tokeep_onlyand name what survives. - A row saved without a value writes
null— harmless mid-edit, worth knowing when you seenulls appear. - Unicode and empty-string names are accepted as literal keys.
Related
- Filter / IF — route or drop items instead of reshaping them.
- Split Out — explode a list field into one item per element.
- Code — arbitrary reshaping in Python when field mapping isn't enough.