<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent posts to JSONByteArrayWriter string result incorrect order</title><link>https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/</link><description>Recent posts to JSONByteArrayWriter string result incorrect order</description><language>en</language><lastBuildDate>Mon, 15 Jun 2026 07:07:11 -0000</lastBuildDate><atom:link href="https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/feed.rss" rel="self" type="application/rss+xml"></atom:link><item><title>JSONByteArrayWriter string result incorrect order</title><link>https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/?limit=25#9a57</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;Hi @TimvH,&lt;/p&gt;
&lt;p&gt;As discussed in our email contact, your example does not actually test/reproduce the bug I am describing:&lt;br/&gt;
Adding to the JSON builder on later cycles works fine.&lt;/p&gt;
&lt;p&gt;Your example works because you do the following:&lt;br/&gt;
1. You finish the first cycle (&lt;code&gt;xFirst&lt;/code&gt;) with adding an object to the array with 2 fields;&lt;br/&gt;
2. When the next cycle is triggered (&lt;code&gt;xAdd&lt;/code&gt;), you immediately start with adding another object to that array.&lt;/p&gt;
&lt;p&gt;This works fine as the last thing you did before #2 was the addition of the array and an object to it.&lt;/p&gt;
&lt;p&gt;To reproduce the bug you should be doing the following instead, as I showed with the code I shared with my first post:&lt;br/&gt;
1. Create the array - save the index that is returned;&lt;br/&gt;
2. Add an item, either a primitive or an object, to the array;&lt;br/&gt;
3. Add an item &lt;em&gt;outside&lt;/em&gt; the array (anything: a primitive, a new array, a nested object, etc);&lt;br/&gt;
4. Add another item to the array using the index you saved at #1.&lt;/p&gt;
&lt;p&gt;You will now see, as I shared in my initial post, that the second item is placed completely outside the root JSON object.&lt;br/&gt;
This also happens to &lt;em&gt;anything else&lt;/em&gt; you try to add after step #4: &lt;em&gt;everything&lt;/em&gt; after this point will be added outside the root JSON object: the JSON is completely broken.&lt;/p&gt;
&lt;p&gt;Important to note is that this not only happens with arrays, but also with nested JSON objects.&lt;br/&gt;
Once you add something outside of a nested JSON object, you can no longer add anything to that nested JSON object, as that causes the exact same bug.&lt;br/&gt;
This also applies to arrays of objects, so if in your test you had tried adding a new key-value pair to the first nested object in your array after you created the second nested object, you would also run into this bug.&lt;/p&gt;
&lt;p&gt;It seems that the &lt;code&gt;JSONByteArrayWriter&lt;/code&gt; (I haven't tested the other writers in the &lt;code&gt;JSON Utilities SL&lt;/code&gt; library, so I don't know if they suffer from the same problem) simply does not handle any JSON fields that add brackets (so arrays with "[" &amp;amp; "]" and nested objects with "{" &amp;amp; "}") well, and closes them prematurely instead of checking if any later JSONElements in the JSONData's array belong to any of these bracketed fields.&lt;br/&gt;
After reviewing the objects &amp;amp; functions of the &lt;code&gt;JSON Utilities SL&lt;/code&gt; library, my guess is that either the &lt;code&gt;JSONByteArrayWriter&lt;/code&gt; linearly goes through the array of &lt;code&gt;JSONElements&lt;/code&gt; in the &lt;code&gt;JSONData&lt;/code&gt; and only checks the &lt;code&gt;diParentIndex&lt;/code&gt; of each &lt;code&gt;JSONElement&lt;/code&gt; in direct ascending order, OR if it does use the &lt;code&gt;JSONElement.GetChildren();&lt;/code&gt; method, that this method is either broken and doesn't give all children correctly to the writer.&lt;br/&gt;
Neither explains why everything completely breaks, and you cannot even add to the root JSON object anymore, however, so there is probably more than just that going wrong in the writer.&lt;/p&gt;
&lt;p&gt;To me, after a full week of testing and attempting workarounds, this seems like a bug in the library that needs to be fixed by Codesys, as I cannot see anything wrong in the &lt;code&gt;JSONData&lt;/code&gt; constructed by the &lt;code&gt;JSONBuilder&lt;/code&gt; - this seems purely a problem in the writer.&lt;/p&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">brouwyka</dc:creator><pubDate>Mon, 15 Jun 2026 07:07:11 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com8e9014d1e4db555a2994c7e313ee9495d4765f1d</guid></item><item><title>JSONByteArrayWriter string result incorrect order</title><link>https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/?limit=25#711c</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;See the example below. You can insert key/value pairs as required&lt;/p&gt;
&lt;p&gt;At first the JSON string will be filled with:&lt;br/&gt;
"{$"Key1$": $"Value0$", $"Key2$": &lt;span&gt;[{$"Key3$": 1, $"Key4$": 2}]&lt;/span&gt;}"&lt;/p&gt;
&lt;p&gt;With xAdd, you can insert items, which will result in:&lt;/p&gt;
&lt;p&gt;"{$"Key1$": $"Value0$", $"Key2$": &lt;span&gt;[{$"Key3$": 1, $"Key4$": 2},{$"Key3$": 3, $"Key4$": 4}]&lt;/span&gt;}"&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;VAR&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;factory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JSONDataFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;eDataFactoryError&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;FBF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ERROR&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;pJsonData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POINTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JSONData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;eError&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eDataFactoryError&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JSONBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;wsValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;WSTRING&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;diRootIndex&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;diObjectIndex1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;diObjectIndex2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;diObjectIndex3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DINT&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;iValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;INT&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;jsonArrayWriter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JSONByteArrayWriter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;wsJsonData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;WSTRING&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;xFirst&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;BOOL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TRUE&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;xWrite&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;BOOL&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;xAdd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;BOOL&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;END_VAR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;xFirst&lt;/span&gt; &lt;span class="kr"&gt;THEN&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pJsonData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pJsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diRootObj&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;diRootIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;wsValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Value0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Key1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wsValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diRootIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;diObjectIndex1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wsKey&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Key2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diRootIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;diObjectIndex2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;iValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Key3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;iValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Key4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;xFirst&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;xWrite&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_IF&lt;/span&gt;
&lt;span class="kr"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;xAdd&lt;/span&gt; &lt;span class="kr"&gt;THEN&lt;/span&gt;
    &lt;span class="n"&gt;xAdd&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;diObjectIndex3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;iValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Key3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;iValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;fb_JBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetKeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Key4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diParentIndex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diObjectIndex3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;xWrite&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_IF&lt;/span&gt;
&lt;span class="kr"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;xWrite&lt;/span&gt; &lt;span class="kr"&gt;THEN&lt;/span&gt;
    &lt;span class="n"&gt;xWrite&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;jsonArrayWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;xExecute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;wsLinebreak&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pwData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ADR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wsJsonData&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;udiSize&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SIZEOF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wsJsonData&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pJsonData&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;xAsyncMode&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;END_IF&lt;/span&gt;
&lt;span class="kr"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;jsonArrayWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xDone&lt;/span&gt; &lt;span class="kr"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;jsonArrayWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xError&lt;/span&gt; &lt;span class="kr"&gt;THEN&lt;/span&gt;
    &lt;span class="n"&gt;jsonArrayWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xExecute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pwData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ADR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wsJsonData&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;udiSize&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SIZEOF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wsJsonData&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pJsonData&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xAsyncMode&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;END_IF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">TimvH</dc:creator><pubDate>Sun, 14 Jun 2026 10:33:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com09423fb8ce8e7fa869a78c4992b785a9db34df73</guid></item><item><title>JSONByteArrayWriter string result incorrect order</title><link>https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/?limit=25#2821</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;Additional note: When doing all additions to a JSON array one after another without additions outside the array inbetween (and no more additions to the array after an item outside the array has been added) - which is &lt;strong&gt;not&lt;/strong&gt; a viable solution for us as we might add items to any of the arrays at any time, but we tested regardless to be thorough - we get the following result:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"machine_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"readings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;"temp_mid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;153.8&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;"temp_mid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;98.3&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RUNNING"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This &lt;em&gt;mostly&lt;/em&gt; matches our expected outcome, aside from the &lt;code&gt;JSONByteArrayWriter&lt;/code&gt; not adding indenting before closing square brackets ("]") at all. That doesn't matter for JSON of course, as it's not sensitive to indenting, but it's still a bug regardless.&lt;/p&gt;
&lt;p&gt;I also want to reiterate that this is not a viable workaround for the issue for us - we have to be able to add to any array at any time, which should be possible according to the docs, and we are 100% sure indexes are correctly being managed and built up by the JSONBuilder and our wrapper (to track the index of each array &amp;amp; the latest item added to each exactly to make use of the &lt;em&gt;documented&lt;/em&gt; possibility to add anything anywhere in the JSON at any time as long as you keep track of the returned indexes) around it.&lt;/p&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">brouwyka</dc:creator><pubDate>Wed, 10 Jun 2026 06:28:25 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.comd54d83e42ad4d269b343be9c76deead913551398</guid></item><item><title>JSONByteArrayWriter string result incorrect order</title><link>https://forge.codesys.com/forge/talk/Engineering/thread/9afc7c8bad/?limit=25#68e7</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;Hello everybody!&lt;/p&gt;
&lt;p&gt;We are currently working on implementing a call to an API that tracks data sent to it through a JSON body.&lt;br/&gt;
Versions: &lt;code&gt;CODESYS V3.5 SP19 Patch 7&lt;/code&gt; using &lt;code&gt;IIOT Libraries SL&lt;/code&gt; license, specifically &lt;code&gt;JSON Utilities SL&lt;/code&gt; version &lt;code&gt;1.13.0.0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For simplicity, let's say we want to construct the following JSON body for our request (simplified to just 1 key-value pair in each of the array objects to keep things shorter, but we'd have multiple fields in each in reality):&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
    "id": "machine_1",
    "readings": [
        {
            "temp_mid": 153.8
        },
        {
            "temp_mid": 98.3
        }
    ],
    "status": "RUNNING"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, our "readings" data is added over time, not in creation, so calls to the builder would be somewhat out of order. In a simplified manner, our calls would look like this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;jsonBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pJsonData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diRootObj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rootJsonIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rootJsonIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;wsValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"machine_1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;jsonBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;Set&lt;/span&gt;&lt;span class="n"&gt;KeyWithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wsValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diParentIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rootJsonIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JSONData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diParentIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;VALUE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diParentIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;passes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;our&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"readings"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;doesn&lt;/span&gt;&lt;span class="s1"&gt;'t exist yet, so we make it first at root JSON object before adding our first reading.&lt;/span&gt;
&lt;span class="s1"&gt;readingsJsonArrayIndex := jsonBuilder.SetKeyWithArray("readings", diParentIndex := rootJsonIndex); // JSONData KEY: diParentIndex = 0 &amp;amp; diIndex = 3, VALUE: diParentIndex = 3 &amp;amp; diIndex = 4.&lt;/span&gt;

&lt;span class="s1"&gt;// Then add the first reading, for which we first have to make an object.&lt;/span&gt;
&lt;span class="s1"&gt;readingsJsonArrayObjectIndex := jsonBuilder.SetObject(diParentIndex := readingsJsonArrayIndex); // JSONData OBJECT: diParentIndex = 4 &amp;amp; diIndex = 5.&lt;/span&gt;

&lt;span class="s1"&gt;// And then we add the field(s) in the object for the first reading.&lt;/span&gt;
&lt;span class="s1"&gt;// NOTE the use of `readingsJsonArrayObjectIndex` so we set the field(s) in the first object in the array.&lt;/span&gt;
&lt;span class="s1"&gt;rValue := 153.8;&lt;/span&gt;
&lt;span class="s1"&gt;jsonBuilder.SetKeyWithValue("temp_mid", wsValue, diParentIndex := readingsJsonArrayObjectIndex); // JSONData KEY: diParentIndex = 5 &amp;amp; diIndex = 6, VALUE: diParentIndex = 6 &amp;amp; diIndex = 7.&lt;/span&gt;

&lt;span class="s1"&gt;// ... Time passes, we want to add another root-JSON-level field ...&lt;/span&gt;

&lt;span class="s1"&gt;// Set "status" at root JSON object.&lt;/span&gt;
&lt;span class="s1"&gt;wsValue := "RUNNING";&lt;/span&gt;
&lt;span class="s1"&gt;jsonBuilder.SetKeyWithValue("status", wsValue, diParentIndex := rootJsonIndex); // JSONData KEY: diParentIndex = 0 &amp;amp; diIndex = 8, VALUE: diParentIndex = 8 &amp;amp; diIndex = 9.&lt;/span&gt;

&lt;span class="s1"&gt;// ... Time passes, we want to add a second reading ...&lt;/span&gt;

&lt;span class="s1"&gt;// "readings" array exists, so add the second reading, but first we have to make another object.&lt;/span&gt;
&lt;span class="s1"&gt;// NOTE the re-use of the earlier stored `readingsJsonArrayIndex`, so we add the new object to that previously created array.&lt;/span&gt;
&lt;span class="s1"&gt;readingsJsonArrayObjectIndex := jsonBuilder.SetObject(diParentIndex := readingsJsonArrayIndex); // JSONData OBJECT: diParentIndex = 4 &amp;amp; diIndex = 10.&lt;/span&gt;

&lt;span class="s1"&gt;// And then we add the field(s) in the object for the first reading.&lt;/span&gt;
&lt;span class="s1"&gt;// NOTE the use of `readingsJsonArrayObjectIndex` so we set the field(s) in the SECOND(, new) object in the array.&lt;/span&gt;
&lt;span class="s1"&gt;rValue := 98.3;&lt;/span&gt;
&lt;span class="s1"&gt;jsonBuilder.SetKeyWithValue("temp_mid", wsValue, diParentIndex := rootJsonIndex); // JSONData KEY: diParentIndex = 10 &amp;amp; diIndex = 11, VALUE: diParentIndex = 11 &amp;amp; diIndex = 12.&lt;/span&gt;

&lt;span class="s1"&gt;// ... Finally, we want to send to the API, so we must convert the builder to data the client accepts as a body ...&lt;/span&gt;

&lt;span class="s1"&gt;xTestWriteToJsonArray := TRUE;&lt;/span&gt;

&lt;span class="s1"&gt;jsonArrayWriter(&lt;/span&gt;
&lt;span class="s1"&gt;    xExecute    := xTestWriteToJsonArray,&lt;/span&gt;
&lt;span class="s1"&gt;    pwData      := ADR(jsonDataString),&lt;/span&gt;
&lt;span class="s1"&gt;    udiSize     := SIZEOF(jsonDataString),&lt;/span&gt;
&lt;span class="s1"&gt;    jsonData    := JsonData^&lt;/span&gt;
&lt;span class="s1"&gt;);&lt;/span&gt;

&lt;span class="s1"&gt;IF jsonArrayWriter.xDone THEN&lt;/span&gt;
&lt;span class="s1"&gt;    // --- The writer was successful, the `jsonDataString` VAR should now contain a WString copy of the JSON object from the builder.           &lt;/span&gt;
&lt;span class="s1"&gt;    xTestWriteToJsonArray := FALSE;&lt;/span&gt;
&lt;span class="s1"&gt;END_IF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We see that the &lt;code&gt;JsonData&lt;/code&gt; STRUCT is correctly organised (in terms of the &lt;code&gt;diParentIndex&lt;/code&gt; &amp;amp; &lt;code&gt;diIndex&lt;/code&gt; set by it for each &lt;code&gt;JsonElement&lt;/code&gt;) as we expect, as outlined in my comments in the simplified code above.&lt;br/&gt;
However, as soon as we pass it to the &lt;code&gt;jsonArrayWriter&lt;/code&gt; (which is a &lt;code&gt;JSON.JSONByteArrayWriter&lt;/code&gt;), the resulting &lt;code&gt;jsonDataString&lt;/code&gt; does not match our expectations, instead coming out like this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
    "id": "machine_1",
    "readings": [
        {
            "temp_mid": 153.8
        }
    ]
}
{
    "temp_mid": 98.3
}
"status": "RUNNING"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The behaviour of the &lt;code&gt;JSONByteArrayWriter&lt;/code&gt; thus seems to be the problem here. It does not seem to correctly process the children of &lt;code&gt;JsonElement&lt;/code&gt;s that are ARRAYs when additions to them are done broken up by additions to the lower level JSON OBJECT they are a part of. We have confirmed this by changing the order of the calls in our example to add both readings before adding the &lt;code&gt;"status"&lt;/code&gt;, in which case we get our expected outcome. However, in reality this is not possible for us - additions to any of the JSON's objects, arrays or array objects may happen at any time after other fields elsewhere in the JSON have been added.&lt;/p&gt;
&lt;p&gt;Does anyone know a way around this, a fix, or knows a solution we simply have not found?&lt;/p&gt;
&lt;p&gt;This same phenomenon was also noted on this forum by user &lt;a class="user-mention" href="/u/ryusoup/profile/"&gt;@ryusoup&lt;/a&gt; at the end of 2023 (https://forge.codesys.com/forge/talk/Engineering/thread/c45929e2f1/#e27f) and user &lt;a class="user-mention" href="/u/mtho/profile/"&gt;@mtho&lt;/a&gt; in early 2024 (https://forge.codesys.com/forge/talk/Engineering/thread/cd1bb450db/#1292) but both topics received no activity beyond both users' opening posts.&lt;br/&gt;
Looking through the release notes of all the versions of the JSON Utilities SL library, I also did not see any remarks on resolutions of bugs in this vain.&lt;/p&gt;
&lt;p&gt;Thanks in advance for the assistance!&lt;/p&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">brouwyka</dc:creator><pubDate>Wed, 10 Jun 2026 05:52:19 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com03ecb925a619fdba4bf23f2fbe9c84ac477deddf</guid></item></channel></rss>