Queue results in Operation is not valid due to the current state of the object using Peek?

I am getting this error using Queue.peek in a dynamic world script:

InvalidOperationException: Operation is not valid due to the current state of the object
System.Collections.Generic.Queue`1[UnityEngine.Transform].Peek ()
GameController.Update () (at Assets/Game Assets/Scripts/Gameplay/GameController.cs:62)

This error is being generated by a track generator script that uses Queue. Up to a point, I can build the track, push it into the queue, and then see it work, but as soon as Update tries to use the queue I created, it fails. The code itself is fairly basic and “seems” to work:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using WeightedRandomization;

public class GameController : MonoBehaviour {

    public static GameController Instance;

    public GameObject Player;

    public Transform Track;
    public Transform StartPoint;

    public float Points;

    public float Distance;

    public int TrackRenderDistance = 14;

    public float RecycleOffset;
    public Vector3 NextPosition;
    public Transform NextPoint;

    public Queue<Transform> ObjectQueue;

    public bool Ready = false;

    void Awake()
    {
        Instance = this;
        ObjectQueue = new Queue<Transform>(TrackRenderDistance);
    }

	void Start ()
    {
        BuildTrack();
    }

    public void BuildTrack()
    {
        for (int i = 0; i < TrackRenderDistance; i++)
        {
            ObjectQueue.Enqueue((Transform)Instantiate(Track));
        }

        NextPosition = StartPoint.position;

        for (int i = 0; i < TrackRenderDistance; i++)
        {
            UpdateTrack();
        }

        Ready = true;
    }
	

	void Update ()
    {
        if (Ready)
        { 
            Transform Peek = ObjectQueue.Peek();

            if (Peek.position.z + RecycleOffset < Distance)
            {
                UpdateTrack();
            }
        }
    }

    public void UpdateTrack()
    {
        Transform o = ObjectQueue.Dequeue();
        Track TrackPoint = o.GetComponent<Track>();

        o.position = NextPosition;

        NextPosition = transform.TransformPoint(TrackPoint.TrackConnectionPoint.position);

    }
}

It is based off the older “Runner” tutorial for Unity3D, although has some changes to accommodate a different structure. Does anyone have any suggestions to fix this?

I would guess that your problem is because you’re calling Dequeue in UpdateTrack which will be reducing the number of items in the list by 1. At some point your queue will be empty so calling Peek() in the Update routine will return null.

My suggestion is that you actually check the size of the queue is greater than 0 before calling Peek and if it is 0, don’t continue. I’d also suggest checking that what you Peak is not null, and the same with what you Dequeue, just as a precaution. Example:

void Update ()
     {
         if (Ready)
         { 
           if(ObjectQueue.Count > 0)
           {
             Transform Peek = ObjectQueue.Peek();
 
             if (Peek.position.z + RecycleOffset < Distance)
             {
                 UpdateTrack();
             }
           }
         }
     }