StackOverflowException in Unity: the requested operation caused a stack overflow

ConsoleRuntime exception · Scripting

StackOverflowException: The requested operation caused a stack overflow.

A method called itself, directly or through other methods, with nothing to stop it, until the call stack ran out. In Unity this can freeze or silently close the Editor, so you may never see the message at all.

Read the Console line first

If the Console shows it, the stack trace repeats the same method over and over: that method is the loop. If the Editor froze instead, think back to the last property or method you changed.

Common causes

  1. A property returns itself

    The classic: a property's getter returns the property instead of its backing field, so reading it reads it again, forever.

    Example
    C#
    private float health;
    
    public float Health
    {
        get { return Health; }   // calls itself: should be health
        set { Health = value; }  // same mistake
    }
  2. Two methods call each other

    A calls B and B calls A with no exit, for example an OnValueChanged handler that sets the value it is listening to.

  3. Recursion with no stopping case

    A method that walks children, splits rooms or retries never reaches the case that returns.

The fix

Fix
C#
private float health;

public float Health
{
    get => health;
    set => health = Mathf.Max(0, value);
}

Stop it coming back

Name backing fields differently from their properties (health and Health, or _health), and give every recursive method its exit condition before its recursive call.

Questions

Why did Unity freeze or crash instead of showing the error?
Very deep recursion can take down the Editor before it logs anything. Save often while working on recursive code, and add a depth limit while you debug it.
How do I write a property without calling itself?
Store the value in a separate backing field: private int health; public int Health { get => health; set => health = Mathf.Max(0, value); }. Returning Health from inside its own getter calls the getter again forever.
Can events cause this too?
Yes. A handler that changes a value which raises the same event again loops forever, for example an OnHealthChanged handler that sets health. Guard with a check that the value actually changed before raising the event.

Scripts that avoid it

Related errors

Got a different error? Paste it into the error lookup.