microg/GmsCore · error · IllegalStateException
Task is not yet completed
Error message
Task is not yet completed
What it means
DuplicateTaskCompletionException.of(task) is a factory that builds the exception describing a Task that was completed more than once. It defensively throws IllegalStateException 'Task is not yet completed' when the passed Task is not complete, since a duplicate-completion report only makes sense for an already-completed Task.
Source
Thrown at play-services-tasks/src/main/java/com/google/android/gms/tasks/DuplicateTaskCompletionException.java:29
import org.microg.gms.common.PublicApi;
/**
* An exception indicating that something attempted to set a result, exception, or cancellation on a {@link Task} that was already completed.
*/
@PublicApi
public class DuplicateTaskCompletionException extends IllegalStateException {
private DuplicateTaskCompletionException(String s) {
super(s);
}
/**
* Creates a DuplicateTaskCompletionException from a {@link Task}.
*
* The {@link Task} must be complete.
*/
public static DuplicateTaskCompletionException of(Task<?> task) {
if (!task.isComplete()) throw new IllegalStateException("Task is not yet completed");
return new DuplicateTaskCompletionException("Task is already completed");
}
}
View on GitHub (pinned to 157c9d86ac)
Solutions
- Only call of(task) after confirming task.isComplete() returns true
- Check that you are passing the Task being completed, not a different pending Task
- Restructure completion code to guard: if (!task.isComplete()) don't report duplicate completion
Example fix
// before
throw DuplicateTaskCompletionException.of(pendingTask); // throws IllegalStateException
// after
if (task.isComplete()) {
throw DuplicateTaskCompletionException.of(task);
} Defensive patterns
Strategy: type-guard
Type guard
// guard before calling the factory
if (!task.isComplete()) {
return; // not a duplicate completion; skip reporting
} Try / catch
try {
throw DuplicateTaskCompletionException.of(task);
} catch (IllegalStateException e) {
// task was not actually complete; wrong Task passed
} Prevention
- Only invoke DuplicateTaskCompletionException.of on tasks where isComplete() is true
- Verify you pass the same Task instance that the completion path targets
- Unit-test TaskCompletionSource wrappers for both complete and pending paths
When it happens
Trigger: Invoking DuplicateTaskCompletionException.of(task) with a Task whose isComplete() returns false — i.e. calling it from code that tries to complete a Task but the Task instance passed in is actually still pending.
Common situations: Custom Task completion logic (e.g. TaskCompletionSource wrappers) that reports duplicate completion without first checking task.isComplete(); passing the wrong (pending) Task to the factory.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Must not be invoked on main thread
- Task is not yet complete
- Only one extension per type may be added
- Cannot add twice the same OnSwitchChangeListener
- Cannot remove OnSwitchChangeListener
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/885810e237974c26.
Report an issue: GitHub.