google/guava · error · UnsupportedOperationException
scheduleWithFixedDelay is not supported.
Error message
scheduleWithFixedDelay is not supported.
What it means
SameThreadScheduledExecutorService is a deliberately minimal synchronous test double that runs submitted tasks on the caller thread. It implements one-shot scheduling but intentionally does not support periodic scheduling; scheduleWithFixedDelay throws UnsupportedOperationException by design.
Source
Thrown at android/guava-testlib/src/com/google/common/util/concurrent/testing/SameThreadScheduledExecutorService.java:186
}
@Override
public int compareTo(Delayed other) {
Preconditions.checkNotNull(other, "other must not be null!");
return 0;
}
}
@Override
public ListenableScheduledFuture<?> scheduleAtFixedRate(
Runnable command, long initialDelay, long period, TimeUnit unit) {
throw new UnsupportedOperationException("scheduleAtFixedRate is not supported.");
}
@Override
public ListenableScheduledFuture<?> scheduleWithFixedDelay(
Runnable command, long initialDelay, long delay, TimeUnit unit) {
throw new UnsupportedOperationException("scheduleWithFixedDelay is not supported.");
}
}
View on GitHub (pinned to 94f39958ba)
Solutions
- Switch the test to a real ScheduledThreadPoolExecutor (or a more complete fake) for code paths that use scheduleWithFixedDelay.
- Refactor the code under test to depend on a Scheduler abstraction so the periodic path can be stubbed without this executor.
- Split the test so periodic scheduling is exercised against a real executor while synchronous parts use the fake.
- Replace fixed-delay scheduling with chained one-shot schedule(...) calls the fake does support.
Example fix
// before SameThreadScheduledExecutorService ex = new SameThreadScheduledExecutorService(); ex.scheduleWithFixedDelay(task, 0, 1, SECONDS); // UnsupportedOperationException // after ScheduledExecutorService ex = Executors.newScheduledThreadPool(1); ex.scheduleWithFixedDelay(task, 0, 1, SECONDS);
Defensive patterns
Strategy: validation
Validate before calling
boolean usesFixedDelay = schedulingType == SchedulingType.WITH_FIXED_DELAY;
ScheduledExecutorService ex = usesFixedDelay
? Executors.newScheduledThreadPool(1)
: new SameThreadScheduledExecutorService(); Type guard
boolean supportsFixedDelay(ScheduledExecutorService ex) {
return !(ex instanceof SameThreadScheduledExecutorService);
} Try / catch
// UnsupportedOperationException signals wrong test double; switch executors, // do not swallow it.
Prevention
- Do not inject SameThreadScheduledExecutorService into code that calls scheduleWithFixedDelay.
- Use a real ScheduledThreadPoolExecutor for fixed-delay paths.
- Abstract scheduling behind an interface so tests can stub it directly.
- Confirm which scheduling operations the fake supports before wiring it.
When it happens
Trigger: Code under test calls executor.scheduleWithFixedDelay(command, initialDelay, delay, unit) on an instance of SameThreadScheduledExecutorService provided by a test.
Common situations: Injecting this fake executor into code that performs periodic scheduling with a fixed delay between completions (e.g. backoff retries, heartbeat loops); tests migrated from a real ScheduledExecutorService without noticing the fake omits fixed-delay scheduling.
Related errors
- scheduleAtFixedRate is not supported.
- Unexpected interrupt while waiting for future
- Unexpected interrupt while waiting for latch
- %s returns null and cannot be used to test instance methods.
- at index %s
AI-assisted analysis of google/guava@94f39958ba (2026-08-13).
Data as JSON: /api/errors/5c0718c2653658f3.
Report an issue: GitHub.