Dissable Reload Domain on play mode cause Missing Reference Exception:

MissingReferenceException: The object of type ‘Image’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

Holy smokes im going crazy with this issue, i dont know if it was my fault or unity bug anymore.

The first time i play in the editor the code works fine, but when i reload play without reload domain, it gives the error above.

Full error log :
‘’’
MissingReferenceException: The object of type ‘Image’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
InventorySystem.UI.Item.UI_Item.SetData (UnityEngine.Sprite sprite, System.Int32 quantity) (at Assets/Scripts/InventoryUI/UI_Item.cs:54)
InventorySystem.UI.Inventory.UI_Inventory.UpdateData (System.Int32 itemIndex, UnityEngine.Sprite itemImage, System.Int32 itemQuantity) (at Assets/Scripts/InventoryUI/UI_Inventory.cs:72)
InventorySystem.Controller.InventoryManager.UpdateInventoryUI (System.Collections.Generic.Dictionary2[TKey,TValue] inventoryState) (at Assets/Scripts/InventoryUI/InventoryManager.cs:43) InventorySystem.Model.Inventory.InventorySO.InformAboutChange () (at Assets/Scripts/Model/InventorySO.cs:80) InventorySystem.Model.Inventory.InventorySO.SwapItems (System.Int32 itemIndex1, System.Int32 itemIndex2) (at Assets/Scripts/Model/InventorySO.cs:68) InventorySystem.Model.Inventory.InventorySO.CreateMouseSelectItem (System.Int32 itemIndex) (at Assets/Scripts/Model/InventorySO.cs:60) InventorySystem.Controller.InventoryManager.HandleItemSelection (System.Int32 itemIndex) (at Assets/Scripts/InventoryUI/InventoryManager.cs:60) InventorySystem.UI.Inventory.UI_Inventory.HandleSelection (InventorySystem.UI.Item.UI_Item item) (at Assets/Scripts/InventoryUI/UI_Inventory.cs:86) InventorySystem.UI.Item.UI_Item.OnPointerClick (UnityEngine.EventSystems.PointerEventData pointerData) (at Assets/Scripts/InventoryUI/UI_Item.cs:86) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1] functor) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)
‘’’

The Code :

‘’’
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEditor.PackageManager.Requests;
using UnityEditor.Presets;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace InventorySystem.UI.Item
{
public class UI_Item : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDropHandler, IDragHandler
{
[SerializeField]
private Image itemImage;
[SerializeField]
private Image borderImage;

    [SerializeField]
    private TMP_Text quantityTxt;



    public event Action<UI_Item> OnItemHoverEnter, OnItemHoverExit, OnItemLeftClick, OnItemRightClick;

    private bool isEmpty = true;

    public void Awake()
    {
        ResetData();
    }

    public void ToggleBorder(bool value)
    {   
        borderImage.enabled = value;
    }


    public void ResetData()
    {
        itemImage.enabled = false;
        quantityTxt.enabled = false;
        isEmpty = true;
    }

    public void SetData(Sprite sprite, int quantity)
    {
        !!!!!! THE ERROR POINT TO THIS LINE OF CODE !!!!!!
        itemImage.enabled = true;
        quantityTxt.enabled = true;
        itemImage.sprite = sprite;
        quantityTxt.text = quantity + "";
        isEmpty = false;
    }

    //public void OnHoverEnter()
    //{
    //    if (isEmpty) return;
    //    OnItemHoverEnter?.Invoke(this);
    //}

    //public void OnHoverExit()
    //{
    //    OnItemHoverExit?.Invoke(this);
    //}

    //public void OnRightClick()
    //{
    //    if (isEmpty) return;
    //    OnItemRightClick?.Invoke(this);
    //}

    public void OnPointerClick(PointerEventData pointerData)
    {
        if (pointerData.button == PointerEventData.InputButton.Right)
        {
            OnItemRightClick?.Invoke(this);
        }
        else
        {
            OnItemLeftClick?.Invoke(this);
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
    }

    public void OnDrop(PointerEventData eventData)
    {
    }

    public void OnDrag(PointerEventData eventData)
    {
    }
}

}
‘’’

You are probably finding an Image from a previous Play that’s been destroyed, but the reference is still alive due to a static reference or a singleton with that reference. Every object that registers to a static event or list needs to be deregistered or you need to clear that list / event on reload.

Follow this guide: Unity - Manual: Domain Reloading

Here’s a little script to help you find all statics in your assembly. It’ll also pick up constants iirc, but the important part is to go through them all and make sure you reset static fields according to the above guide wherever it might be consequential.

public sealed class PrintStatics : MonoBehaviour
{
    void Start()
    {
        var types = Assembly.GetExecutingAssembly().DefinedTypes;

        var query = types.GroupBy(
            type => type,
            (type, data) => new
            {
                Type = type,
                Fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).ToList(),
                Properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).ToList(),
                Events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).ToList(),
            });

        StringBuilder sb = new();

        foreach (var item in query)
        {
            bool anyStatics = item.Fields.Count > 0 || item.Properties.Count > 0 || item.Events.Count > 0;
            if (!anyStatics)
                continue;

            sb.AppendLine(item.Type.FullName);

            for (int i = 0; i < item.Fields.Count; i++)
                sb.AppendLine($"\tField = {item.Fields[i].Name}");

            for (int i = 0; i < item.Properties.Count; i++)
                sb.AppendLine($"\tProperty = {item.Properties[i].Name}");

            for (int i = 0; i < item.Events.Count; i++)
                sb.AppendLine($"\tEvent = {item.Events[i].Name}");
        }

        Debug.LogWarning(sb);
    }

}