Cysharp/UniTask · error · InvalidOperationException
Already continuation registered, can not await twice or get
Error message
Already continuation registered, can not await twice or get Status after await.
What it means
Thrown by UniTaskCompletionSourceCore<TResult>.OnCompleted when a continuation is already registered and it is not the internal sentinel. UniTask structs are single-await by design: awaiting the same UniTask twice, or calling GetStatus/OnCompleted after awaiting, is invalid because the underlying source may have been returned to a pool. The guard detects double-registration of continuations.
Source
Thrown at src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs:291
C.1: win OnCompleted -> TrySet invoke saved continuation
C.2: win TrySet -> should invoke continuation here.
*/
// not set continuation yet.
object oldContinuation = this.continuation;
if (oldContinuation == null)
{
continuationState = state;
oldContinuation = Interlocked.CompareExchange(ref this.continuation, continuation, null);
}
if (oldContinuation != null)
{
// already running continuation in TrySet.
// It will cause call OnCompleted multiple time, invalid.
if (!ReferenceEquals(oldContinuation, UniTaskCompletionSourceCoreShared.s_sentinel))
{
throw new InvalidOperationException("Already continuation registered, can not await twice or get Status after await.");
}
continuation(state);
}
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ValidateToken(short token)
{
if (token != version)
{
throw new InvalidOperationException("Token version is not matched, can not await twice or get Status after await.");
}
}
}
internal static class UniTaskCompletionSourceCoreShared // separated out of generic to avoid unnecessary duplicationView on GitHub (pinned to ceac8d6946)
Solutions
- Await each UniTask exactly once; create a new UniTask for repeated operations
- If you need multiple consumers, use UniTaskCompletionSource and expose Task multiple times, or broadcast via IUniTaskAsyncEnumerable
- Never call GetStatus or OnCompleted on a UniTask after it has been awaited
- Avoid storing UniTask in long-lived fields; await it immediately or convert to a re-awaitable source
Example fix
// before var task = DoSomethingAsync(); await task; await task; // throws: already awaited // after await DoSomethingAsync(); await DoSomethingAsync(); // create a new task each time
Defensive patterns
Strategy: validation
Validate before calling
// UniTask is single-await; ensure you only await once // If you need multi-consumer, use UniTaskCompletionSource: var ucs = UniTaskCompletionSource.Create(); ucs.TrySetResult(); // ucs.Task can be awaited multiple times via separate UniTask instances
Prevention
- Never await the same UniTask variable twice
- Do not call GetStatus or OnCompleted after awaiting
- Do not store UniTask in long-lived fields; await immediately
- Use UniTaskCompletionSource or IUniTaskAsyncEnumerable for multi-consumer scenarios
When it happens
Trigger: Awaiting the same UniTask variable twice. Calling GetStatus after await on the same UniTask. Storing a UniTask in a field and awaiting it from multiple call sites. Pooling issues where a returned UniTaskCompletionSourceCore is reused while a stale continuation is still registered.
Common situations: Storing a UniTask and awaiting it in a loop or retry logic. Passing a UniTask to multiple consumers. Debugging code that inspects status after the task has already been awaited. Misusing pooled AutoResetUniTaskCompletionSource.
Related errors
- Not yet completed, UniTask only allow to use await.
- Token version is not matched, can not await twice or get Sta
- not yet completed.
- continuation
- Can not trigger itself in iterating.
AI-assisted analysis of Cysharp/UniTask@ceac8d6946 (2026-08-13).
Data as JSON: /api/errors/9c2aa4c1b4e002b6.
Report an issue: GitHub.