stride3d/stride · error · InvalidOperationException

The deque is empty.

Error message

The deque is empty.

What it means

Thrown by RemoveFromBack when the deque has no elements. Removing and returning the last element is undefined on an empty deque, so the method fails fast with InvalidOperationException rather than returning a default value.

Solutions

  1. Check IsEmpty (or Count > 0) before calling RemoveFromBack
  2. Wrap the call in try/catch for InvalidOperationException if drain-until-empty semantics are intended
  3. Prefer TryRemove-type patterns or Count checks inside drain loops

Example fix

// before
while (true) { var item = deque.RemoveFromBack(); Process(item); } // throws when empty
// after
while (!deque.IsEmpty) { var item = deque.RemoveFromBack(); Process(item); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!deque.IsEmpty) { var item = deque.RemoveFromBack(); ... }

Try / catch

try { var item = deque.RemoveFromBack(); Process(item); }
catch (InvalidOperationException ex) when (ex.Message == "The deque is empty.") { /* empty: nothing to remove */ }

Prevention

When it happens

Trigger: Calling deque.RemoveFromBack() when IsEmpty is true — typically one more call than the number of AddToFront/AddToAddBack calls, or on a freshly constructed deque.

Common situations: Draining loops without checking IsEmpty; queue-consumer code that races ahead of producers in single-threaded pipelines; reusing a deque after Clear() without rechecking emptiness.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/260e3c75affb294a. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core/Collections/Dequeue.cs:878

        CheckRangeArguments(Count, offset, count);

        if (count == 0)
        {
            return;
        }

        DoRemoveRange(offset, count);
    }

    /// <summary>
    /// Removes and returns the last element of this deque.
    /// </summary>
    /// <returns>The former last element.</returns>
    /// <exception cref="InvalidOperationException">The deque is empty.</exception>
    public T RemoveFromBack()
    {
        if (IsEmpty)
            throw new InvalidOperationException("The deque is empty.");

        return DoRemoveFromBack();
    }

    /// <summary>
    /// Removes and returns the first element of this deque.
    /// </summary>
    /// <returns>The former first element.</returns>
    /// <exception cref="InvalidOperationException">The deque is empty.</exception>
    public T RemoveFromFront()
    {
        if (IsEmpty)
            throw new InvalidOperationException("The deque is empty.");

        return DoRemoveFromFront();
    }

    /// <summary>

View on GitHub (pinned to 96fad776d2)