title: System.JSONException: Current context not an ARRAY but OBJECT
body: <p>I have a custom Salesforce object Category__c that has a self look up to itself upto 3 levels. I have written the below code to construct a JSON from this object. But I am facing a run time error:</p>
  
  <blockquote>
    <p>System.JSONException: Current context not an ARRAY but OBJECT</p>
  </blockquote>
  
  <p>Can someone please point out where I am going wrong there.</p>
  
  <p>I found the below post relevant to this error, but I am not able to relate to it since it is in a different platform.
  <a href="https://stackoverflow.com/questions/30186152/elasticsearchcurrent-context-not-an-array-but-object-when-trying-to-index-an-ar">ElasticSearch:Current context not an ARRAY but OBJECT when trying to index an array</a></p>
  
  <p>Apex Code:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>public class lsRestResourceHandler {
  public static String getCategoriesJSON() {
      
          boolean l2fieldset = false;
          
          //Query list of Categories
          list&lt;Category__c&gt; lstCategories = new list&lt;Category__c&gt;([SELECT Parent_Category__r.Level__c
                                                                  , Parent_Category__r.Id
                                                                  , Parent_Category__r.Name
                                                                  , Level__c
                                                                  , Id
                                                                  , Name
                                                                  , (SELECT Level__c, Id, Name FROM SubCategories__r) 
                                                                  FROM Category__c WHERE Level__c=2 OR Level__c=1]);
          Set&lt;Id&gt; setParentCategories = new Set&lt;Id&gt;();
          for(Category__c category:lstCategories) {
              setParentCategories.add(category.Parent_Category__r.Id);
          }
          //Start JSON Generator
          JSONGenerator categoryJSON = JSON.createGenerator(true);
          categoryJSON.writeStartObject();
          categoryJSON.writeFieldName('Categories');
          categoryJSON.writeStartArray();
          //Iterate through 1st level1 Categories            
          for(Category__c level1:lstCategories) {            
              if(level1.Level__c == 1){
                  categoryJSON.writeStartObject();
                  categoryJSON.writeStringField('Id',level1.Id);
                  categoryJSON.writeStringField('Name',level1.Name);
                  
                  if(setParentCategories.contains(level1.Id)) {
                      categoryJSON.writeFieldName('SubCategories');
                      categoryJSON.writeStartArray();
                      for(Category__c level2:lstCategories) {
                          //If Level1 is parent category for any level2 categories, iterate through them
                          if(level1.Id == level2.Parent_Category__r.Id) {
                              categoryJSON.writeStartObject();
                              categoryJSON.writeStringField('Id',level2.Id);
                              categoryJSON.writeStringField('Name',level2.Name);
                              
                              //If level2 category has level3 SubCategories, iterate through them
                              if(level2.SubCategories__r != null) {
                                  categoryJSON.writeFieldName('SubCategories');
                                  categoryJSON.writeStartArray();
                                  for(category__c level3:level2.SubCategories__r) {
                                      categoryJSON.writeStartObject();
                                      categoryJSON.writeStringField('Id',level3.Id);
                                      categoryJSON.writeStringField('Name',level3.Name);
                                      categoryJSON.writeEndObject();
                                  }
                                  categoryJSON.writeEndArray();
                              }
                              categoryJSON.writeEndObject();
                          }
                      }
                      categoryJSON.writeEndArray();
                      categoryJSON.writeEndObject();
                  }                
              }
          }
          categoryJSON.writeEndArray();
          categoryJSON.writeEndObject();
          //Convert to JSON String
          String strCategoryJSON = categoryJSON.getAsString();
          return strCategoryJSON;
      }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>Target JSON Format:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>{
      "Categories":[
      {
          "Id":"5",
          "Name":"Category5",
          "SubCategories":[
              {
                  "Id":"51",
                  "Name":"Cat5Sub1",
                  "SubCategories":[
                      {
                          "Id":"511",
                          "Name":"Cat5Sub1Sub1"
                      },
                      {
                          "Id":"512",
                          "Name":"Cat5Sub1Sub1"
                      }
                  ]
              },
              {
                  "Id":"32",
                  "Name":"Cat5Sub2",
                  "SubCategories":[
                      {
                          "Id":"511",
                          "Name":"Cat5Sub1Sub2"
                      },
                      {
                          "Id":"512",
                          "Name":"Cat5Sub1Sub2"
                      }
                  ]
              },
              {
                  "Id":"33",
                  "Name":"Cat5Sub3"
              }
          ]
      }
  ]
  }</code></pre>
  </div>
  </div>
  </p>