The top and bottom are identical except that on the first set in the bottom “job_id” is set to “Juste CFO\n_test_2025-05-12-06:34:21” whereas it is set to “test” on the top one.
This is to illustrate a working behavior (top) vs a buggy behavior (bottom).
Hi @n8ncmat, I think this comes down to mixing an expression returning JSON with JSON-like text.
The JSON standard doesn’t allow real line breaks, so you’d want to make sure you’re not mixing data types when working with line breaks. You can avoid the by using a single expression instead of mixing text and expressions.
Example (the change is in the Edit Fields node in the bottom right):
Hey @n8ncmat, I’ve posted an updated workflow above which should solve your issue. Perhaps you want to try this and confirm if you’re still hitting any issues?
This Js “object” will evaluate to the primitive type “string” as a whole.
In the second case the set node will output (before json parsing) the following javascript object equivalent of this js code:
let myObject = {
job_id: $json.job_id, // The value is a JavaScript String primitive
step: $json.step, // The value is a JavaScript String primitive
// ... other properties also holding primitive values (mostly strings)
};
// 'myObject' is now a JavaScript Object in memory.
Then this js object can be sucessfully parsed to JSON (by n8n or even JSON.parse() ) with escaped new lines in the string object held by job_id.
Whereas the first one outputs a single primitive string, which - containing an unescaped new line after a doubel quote - cannot be parsed to valid JSON.
Is that a correct/simple way of thinking about it ?
Yes, exactly! That’s pretty much what’s happening here!
In the first case, the Set node will see the input text with expressions mixed in. It will then first resolve the expressions, and afterwards try to process the full text (which now has a line break).
In the second case (where you only have a single expression and nothing else), no text will have to be parsed as JSON as you already return a valid object.