Why is coroutine breaking early?

I have an item that runs the following coroutine just before it is destroyed. For some reason it is only running one frame and then stopping. It seems like it is breaking from the while loop when it should be breaking from the switch. Any ideas what is wrong?

ItemModifyPlayerAttribute.cs

public enum PlayerAttribute
{
    Health,
    /* Other Attributes */
}

public class ItemModifyPlayerAttribute : MonoBehaviour, IUseable
{
    /* Some Properties */

    public void Use()
    {
        /* More Code */

        StartCoroutine(ModifyPlayerAttributeRoutine(PlayerAttribute, Amount, DelayTime, LengthTime, inventoryContainer.GetComponent<PlayerAttributeController>()));
    }

    private static IEnumerator ModifyPlayerAttributeRoutine(PlayerAttribute playerAttribute, float amount, float delayTime, float lengthTime, PlayerAttributeController playerAttributeController)
    {
        if (amount != 0f)
        {
            if (delayTime != 0f)
                yield return new WaitForSeconds(delayTime);

            float totalTime = 0f;

            while (playerAttributeController != null && totalTime < lengthTime)
            {
                float deltaAmount = amount * Time.deltaTime / lengthTime;

                switch (playerAttribute)
                {
                    case PlayerAttribute.Health:
                        playerAttributeController.Health += deltaAmount;
                        break;

                    /* Other Player Attributes */
                }

                totalTime += Time.deltaTime;
                yield return null;
            }
        }
    }
}

InventoryController.cs

/* When player clicks on item */
itemModifyPlayerAttribute.Use();
GameObject.Destroy(inventorySlots[i, j].Item.gameObject);
inventorySlots[i, j] = null;

How are you calling it before Destroy? If you’re only calling StartCoroutine and then call Destroy then it will run only one frame because coroutines are stopped whe the gameobject is destroyed. You should use:

yield return StartCoroutine(YourCoroutine());
Destroy(gameObject);

Or just move Destroy inside your coroutine out of your loop.