Cysharp/UniTask · error · ArgumentOutOfRangeException

Delay does not allow minus delayFrameCount. delayFrameCount:

Error message

Delay does not allow minus delayFrameCount. delayFrameCount:

What it means

Thrown by UniTask.DelayFrame when delayFrameCount is negative. UniTask frame-based delays use a counter that is decremented per frame; a negative starting value has no meaningful semantics. The guard catches accidental sign errors or uninitialized variables at the call site.

Source

Thrown at src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Delay.cs:141

        {
            return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken, cancelImmediately);
        }

		public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
		{
			return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
		}

		public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
		{
			return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
		}

		public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
        {
            if (delayFrameCount < 0)
            {
                throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
            }

            return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, cancelImmediately, out var token), token);
        }

        public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
        {
            var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
            return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
        }

        public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
        {
            var delayType = ignoreTimeScale ? DelayType.UnscaledDeltaTime : DelayType.DeltaTime;
            return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken, cancelImmediately);
        }

        public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)

View on GitHub (pinned to ceac8d6946)

Solutions

  1. Clamp the frame count to zero minimum: Math.Max(0, delayFrameCount)
  2. Use UniTask.Yield() instead of DelayFrame(0) when you need a one-frame wait
  3. Validate inspector-configured values in OnValidate or at startup

Example fix

// before
await UniTask.DelayFrame(myFrameCount); // throws if myFrameCount < 0

// after
await UniTask.DelayFrame(Math.Max(0, myFrameCount));
Defensive patterns

Strategy: validation

Validate before calling

int safeFrames = Math.Max(0, delayFrameCount);
await UniTask.DelayFrame(safeFrames);

Prevention

When it happens

Trigger: Calling UniTask.DelayFrame(-1) or passing a computed frame count that underflows (e.g., subtracting a larger value from a smaller one).

Common situations: Arithmetic on frame counts without clamping, e.g., desiredFrames - extraFrames where extraFrames exceeds desiredFrames. Parameterizing delays via serialized fields in the Unity inspector with invalid defaults.

Related errors


AI-assisted analysis of Cysharp/UniTask@ceac8d6946 (2026-08-13). Data as JSON: /api/errors/d21c613d8ae82afd. Report an issue: GitHub.