Cysharp/UniTask · error · ArgumentOutOfRangeException

Delay does not allow minus periodFrameCount. periodFrameCoun

Error message

Delay does not allow minus periodFrameCount. periodFrameCount:

What it means

Thrown by the two-parameter TimerFrame overload when periodFrameCount is negative. NOTE: there is a bug in the error message — the code interpolates dueTimeFrameCount instead of periodFrameCount (line 42: `"periodFrameCount:" + dueTimeFrameCount`). So the thrown message will display the wrong variable's value, which can mislead debugging. The check itself correctly tests periodFrameCount < 0.

Source

Thrown at src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs:42

        public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
        {
            if (dueTimeFrameCount < 0)
            {
                throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
            }

            return new TimerFrame(dueTimeFrameCount, null, updateTiming, cancelImmediately);
        }

        public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
        {
            if (dueTimeFrameCount < 0)
            {
                throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
            }
            if (periodFrameCount < 0)
            {
                throw new ArgumentOutOfRangeException("Delay does not allow minus periodFrameCount. periodFrameCount:" + dueTimeFrameCount);
            }

            return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancelImmediately);
        }

        public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
        {
            if (intervalFrameCount < 0)
            {
                throw new ArgumentOutOfRangeException("Delay does not allow minus intervalFrameCount. intervalFrameCount:" + intervalFrameCount);
            }
            return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming, cancelImmediately);
        }
    }

    internal class Timer : IUniTaskAsyncEnumerable<AsyncUnit>
    {
        readonly PlayerLoopTiming updateTiming;

View on GitHub (pinned to ceac8d6946)

Solutions

  1. Validate/clamp periodFrameCount: var period = Math.Max(0, periodFrameCount); before calling TimerFrame.
  2. If you want a non-repeating timer, use the single-parameter TimerFrame(dueTimeFrameCount) overload instead of passing a negative period.
  3. Be aware the error message shows dueTimeFrameCount's value due to a source bug — check the periodFrameCount argument you passed.

Example fix

// before
await UniTaskAsyncEnumerable.TimerFrame(5, -1).ForEachAwaitAsync(_ => { });
// throws: 'periodFrameCount: 5' (misleading due to source bug)

// after (non-repeating timer)
await UniTaskAsyncEnumerable.TimerFrame(5).ForEachAwaitAsync(_ => { });
Defensive patterns

Strategy: validation

Validate before calling

var safePeriod = Math.Max(0, periodFrameCount);
await UniTaskAsyncEnumerable.TimerFrame(dueTimeFrameCount, safePeriod).ForEachAwaitAsync(_ => { });
// NOTE: The error message has a bug — it prints dueTimeFrameCount's value
// instead of periodFrameCount. Check the period argument you actually passed.

Prevention

When it happens

Trigger: Passing negative periodFrameCount to TimerFrame(dueTimeFrameCount, periodFrameCount, ...). The due time is checked first, so this only fires if dueTimeFrameCount is valid (>= 0) but periodFrameCount is negative.

Common situations: Setting up a repeating frame timer with a bad period value. Using -1 as a 'no period' sentinel instead of passing null (the single-parameter overload). Copy-paste error in parameter passing.

Related errors


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