ESP32 crashes when calling `lv_obj_clean()`

It seems at some point e was corrupted inside _lv_event_mark_deleted probably because of dangling pointers in your code, as said in the last comment.

Global variables are very bad practice, specially when threads are being used. The error in your code, is not anywhere near the place you call lv_obj_clean, check your global variables, possibily you are calling lv_obj_del before removing some timers, events, animations, that use that object. Maybe you are doing something like lv_obj_get_child but using a wrong index, and assuming something would be inside the user_data of that object, but actually is in other object, or the object has already been destroyed… Unfortunately, you will need to re-read your whole code.

If your project has been configured properly, LVGL will print logs and assertions at some point. Would seriously recommend using PlatformIO instead of the ArduinoIDE, the advantages are countless.

I don’t know if this can help but the crash is happening exactly in this function :

void SearchMyComponents(void* parameters) {
  // static int page = 1;
  int page = (int)parameters;  // Cast back to int
  if (page <= 0) {
    page = 1;
  }
  const char* SearchText = lv_textarea_get_text(ui_TextArea1);
  String SearchTextString = String(SearchText);
  SearchTextString.replace(" ", "+");
  http.begin("https://domain.name/PartSense/api/SearchComponents.php?keyword=" + SearchTextString + "&resultperpage=" + MAX_COMPONENTS + "&page=" + page);

  http.addHeader("Content-Type", "application/json");
  lv_obj_add_flag(ui_No_Result_Container, LV_OBJ_FLAG_HIDDEN);

  // size_t freeHeap = ESP.getFreeHeap();
  // Serial.println("Free heap before JSON parse: " + String(freeHeap));

  // Send HTTP GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode > 0) {
    Serial.println("HTTP Response code: " + String(httpResponseCode));

    // Get the JSON response as a string and print it
    String responseString = http.getString();
    Serial.println("JSON Response: " + responseString);

    // Parse JSON response
    DynamicJsonDocument jsonResponse(2048);  // Adjust size as needed
    DeserializationError error = deserializeJson(jsonResponse, responseString);

    if (!error) {
      // Check if "SearchResults" and "Parts" keys exist
      if (jsonResponse.containsKey("SearchResults") && jsonResponse["SearchResults"].containsKey("NumberOfResult") && jsonResponse["SearchResults"].containsKey("Parts")) {
        int numberOfResult = jsonResponse["SearchResults"]["NumberOfResult"].as<int>();
        JsonArray parts = jsonResponse["SearchResults"]["Parts"].as<JsonArray>();

        // Clear previous component data
        clearComponentData();

        // Create a new screen and switch to it
        lv_obj_t* temp_screen = lv_obj_create(NULL);
        lv_scr_load(temp_screen);
        lv_obj_add_flag(ui_Search_Result, LV_OBJ_FLAG_HIDDEN);

        // Clean old search results safely
        // lv_event_send(ui_Search_Result, LV_EVENT_DELETE, NULL);  // Safely remove any pending events
        // lv_obj_invalidate(ui_Search_Result);                     // Prevent any drawing operations during clean
        lv_obj_clean(ui_Search_Result);  // Still causes crashes
        // lv_obj_del(ui_Search_Result);                          // Still causes crashes

        if (numberOfResult > 0) {
          createProductCardsMyComponents(ui_Search_Result, numberOfResult);
          createChangePage(ui_Search_Result, numberOfResult, page);
          int i = 0;
          for (JsonObject part : parts) {
            if (i >= MAX_COMPONENTS) break;  // Ensure we don't exceed the array size

            descriptions[i] = strdup(part["description"] | "");
            if (!descriptions[i]) {
              Serial.println("Memory allocation failed for descriptions[" + String(i) + "]");
              continue;
            }

            manufacturers[i] = strdup(part["manufacturer"] | "");
            if (!manufacturers[i]) {
              Serial.println("Memory allocation failed for manufacturers[" + String(i) + "]");
              free((void*)descriptions[i]);
              descriptions[i] = nullptr;
              continue;
            }
            partNumbers[i] = strdup(part["part_number"] | "");
            if (!partNumbers[i]) {
              Serial.println("Memory allocation failed for partNumbers[" + String(i) + "]");
              free((void*)descriptions[i]);
              descriptions[i] = nullptr;
              free((void*)manufacturers[i]);
              manufacturers[i] = nullptr;
              continue;
            }

            manufacturerPartNumbers[i] = strdup(part["mpn"] | "");
            if (!manufacturerPartNumbers[i]) {
              Serial.println("Memory allocation failed for manufacturerPartNumbers[" + String(i) + "]");
              free((void*)descriptions[i]);
              descriptions[i] = nullptr;
              free((void*)manufacturers[i]);
              manufacturers[i] = nullptr;
              free((void*)partNumbers[i]);
              partNumbers[i] = nullptr;
              continue;
            }

            // Print extracted data
            Serial.println("Component " + String(i + 1) + ":");
            Serial.println("Description: " + String(descriptions[i]));
            Serial.println("Manufacturer: " + String(manufacturers[i]));
            Serial.println("Manufacturer Part Number: " + String(manufacturerPartNumbers[i]));

            lv_label_set_text(productCardComponents[i].Mfr_Part, manufacturerPartNumbers[i]);
            lv_label_set_text(productCardComponents[i].Description, descriptions[i]);
            lv_label_set_text(productCardComponents[i].Manufacturer, manufacturers[i]);
            lv_label_set_text(productCardComponents[i].Part_Number, partNumbers[i]);
            productCardComponents[i].part_number_const = partNumbers[i];
            const char* partNumberText = lv_label_get_text(productCardComponents[i].Part_Number);
            String response = "https://theyoungmaker.dev/PartSense/images/" + String(partNumberText) + "/96x96.bmp";

            if (imagesEnabled) {
              if (getImageFromURL(response, i)) {
                Serial.println("Image downloaded and processed successfully");
                lv_img_set_src(productCardComponents[i].Image, &productImages[i]);
              } else {
                Serial.println("Failed to download or process image");
              }
            }
            i++;
          }
        } else {
          lv_obj_clear_flag(ui_No_Result_Container, LV_OBJ_FLAG_HIDDEN);
        }
      } else {
        Serial.println("JSON response does not contain expected keys");
      }

      lv_obj_add_flag(ui_Spinner1, LV_OBJ_FLAG_HIDDEN);
      lv_obj_clear_flag(ui_Search_Result, LV_OBJ_FLAG_HIDDEN);

      // Switch back to the original product screen
      lv_scr_load(ui_Component_Search);
    } else {
      Serial.println("Failed to parse JSON: " + String(error.c_str()));
    }
  } else {
    Serial.println("Error on HTTP request: " + http.errorToString(httpResponseCode));
  }
  http.end();
  vTaskDelete(SearchMyComponentsTaskHandle);
}