Cysharp/UniTask · error · InvalidOperationException
Not yet completed, UniTask only allow to use await.
Error message
Not yet completed, UniTask only allow to use await.
What it means
Thrown by UniTaskCompletionSourceCore<TResult>.GetResult when completedCount is zero, meaning the source has not been signaled (no TrySetResult/TrySetException/TrySetCanceled was called). UniTask is await-only by design: calling GetResult directly on an incomplete source is invalid. The guard prevents reading an uninitialized result.
Source
Thrown at src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs:232
public UniTaskStatus UnsafeGetStatus()
{
return (continuation == null || (completedCount == 0)) ? UniTaskStatus.Pending
: (error == null) ? UniTaskStatus.Succeeded
: (error is OperationCanceledException) ? UniTaskStatus.Canceled
: UniTaskStatus.Faulted;
}
/// <summary>Gets the result of the operation.</summary>
/// <param name="token">Opaque value that was provided to the <see cref="UniTask"/>'s constructor.</param>
// [StackTraceHidden]
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TResult GetResult(short token)
{
ValidateToken(token);
if (completedCount == 0)
{
throw new InvalidOperationException("Not yet completed, UniTask only allow to use await.");
}
if (error != null)
{
hasUnhandledError = false;
if (error is OperationCanceledException oce)
{
throw oce;
}
else if (error is ExceptionHolder eh)
{
eh.GetException().Throw();
}
throw new InvalidOperationException("Critical: invalid exception type was held.");
}
return result;View on GitHub (pinned to ceac8d6946)
Solutions
- Ensure every code path that creates a UniTaskCompletionSource calls TrySetResult, TrySetException, or TrySetCanceled
- Use await instead of manually calling GetResult — UniTask is designed for await-only consumption
- Check status before GetResult: if (source.GetStatus(token) != UniTaskStatus.Pending) before accessing the result
Example fix
// before var tcs = new UniTaskCompletionSourceCore<int>(); var result = tcs.GetResult(tcs.Version); // throws: not completed // after var tcs = new UniTaskCompletionSourceCore<int>(); tcs.TrySetResult(42); var result = tcs.GetResult(tcs.Version); // ok
Defensive patterns
Strategy: validation
Validate before calling
if (source.GetStatus(token) == UniTaskStatus.Pending)
{
// not ready; await instead of calling GetResult
throw new InvalidOperationException("Source not yet completed; use await.");
}
var result = source.GetResult(token); Prevention
- Always await UniTask rather than calling GetResult manually
- Ensure all code paths signal TrySetResult/TrySetException/TrySetCanceled
- Add a timeout signal so sources always complete
When it happens
Trigger: Manually calling GetResult on a UniTaskCompletionSourceCore before it is completed. Awaiting a UniTask whose underlying source was never signaled (e.g., a forgotten TrySetResult). Using UniTask.SuppressCancellationThrow() or direct GetResult() on a task that is still pending.
Common situations: Forgetting to call TrySetResult in a callback-based adapter. A code path that creates a UniTaskCompletionSource<T> but the signaling branch is unreachable due to a logic error. Manual interaction with IUniTaskSource outside of the await pattern.
Related errors
- Already continuation registered, can not await twice or get
- not yet completed.
- continuation
- Token version is not matched, can not await twice or get Sta
- Can not trigger itself in iterating.
AI-assisted analysis of Cysharp/UniTask@ceac8d6946 (2026-08-13).
Data as JSON: /api/errors/106147e4ba4828cc.
Report an issue: GitHub.