You returned the right envelope — an item with a json key — but json points at
something that isn't a plain object. n8n's description:
In the returned data, every key named 'json' must point to an object.
The identical check runs on binary, and produces A 'binary' property isn't an object. Everything below applies to both.
This is stricter than JavaScript's typeof, and the exact test is four conditions:
typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date)
So all four of these fail, and three of them surprise people:
| What you returned | Why it fails |
|---|---|
json: null |
typeof null === 'object', but n8n excludes it explicitly |
json: [ … ] |
arrays are objects to JavaScript; n8n excludes them |
json: new Date() |
a Date is an object; n8n excludes it |
json: 'some string', json: 42, json: undefined |
not objects at all |
The array case is the common one. { json: results } where results is an array of
rows reads perfectly and is wrong — each row needs to be its own item:
// throws
return [{ json: rows }];
// right
return rows.map(row => ({ json: row }));
The Date case is the sharp one, because a Date inside json is fine. n8n walks
the contents of json and stringifies anything that isn't a plain object — Dates,
RegExps and the like — at any depth. So { json: { created: new Date() } } works and
comes out as a string, while { json: new Date() } throws. The cleanup applies to what
is inside the envelope, never to the envelope itself.
{ json: undefined } throws, and so does an item where a branch of your code simply
never set json:
return $input.all().map(item => {
const out = {};
if (item.json.active) out.json = { id: item.json.id };
return out; // inactive items have no json at all
});
That's the same failure as json: undefined, and it's the one that shows up on item 40
of 50 rather than on the first item — because it's data-dependent. If this error names a
late item index, look for a conditional that doesn't assign on every path.
return null is a different problemReturning null as your whole result doesn't produce this message. It gets past the
earlier shape checks (typeof null === 'object') and then fails inside n8n's item
normalisation with a plain JavaScript type error rather than a validation message. If
you're seeing a type error with no helpful description, check whether some path returns
null instead of [].
A 'json' property isn't an object [item 4] — item 4 specifically… [line 12, for item 4] — when n8n knows the line as wellItem 0 failing usually means the shape is wrong for every item. A late index almost always means a data-dependent branch, as above.
The json object is what the rest of n8n operates on: expressions resolve against its
keys, the table view renders its columns, and downstream nodes address fields by name.
An array has indices rather than names, a Date has neither, and null has nothing at
all. None of them can carry the field access that every node after this one assumes.
Validating at the boundary is deliberate — the alternative is a workflow that runs another three nodes and then fails with an expression error pointing at code you didn't write.
Source: validateItem and isObject in
packages/nodes-base/nodes/Code/result-validation.ts and utils.ts, and
standardizeOutput in the same utils.ts for the stringify-inside-json behaviour.
Read directly from n8n's repository; the Code node documentation does not list these
error strings.
Last verified 16 September 2026 against n8n 2.39.5 (source read on master @ 2.40.0). n8n changes these messages between releases; if the wording you see differs, the version above is what this page was checked against.