apache/beam · error · RuntimeException
Unexpected null result.
Error message
Unexpected null result.
What it means
This memoizing Supplier wrapper in FnApiTimerBundleTracker caches the result of applying a function and refuses to return a null result, throwing "Unexpected null result." It exists to bridge nullable-checking: a memoized value must be non-null. If the wrapped function ever returns null, this runtime error surfaces instead.
Solutions
- Ensure the wrapped function never returns null (return a sentinel/Optional-compatible value).
- Check why the underlying computation produced null — usually missing state for the queried key.
- Upgrade Beam; this is an internal invariant and a null here indicates a harness bug.
- Capture the stack trace and file an issue with the runner/harness logs.
Example fix
// before Supplier<T> memoized = memoize(arg -> map.get(arg)); // may be null // after Supplier<T> memoized = memoize(arg -> Objects.requireNonNullElse(map.get(arg), DEFAULT));
Defensive patterns
Strategy: validation
Validate before calling
T result = f.apply(arg);
if (result == null) {
throw new IllegalArgumentException("memoized function must not return null");
} Type guard
boolean nonNull(Object o) { return o != null; } Try / catch
try {
T v = memoizedSupplier.get();
} catch (RuntimeException e) {
if ("Unexpected null result.".equals(e.getMessage())) {
LOG.error("Wrapped function returned null — fix the mapping", e);
} else { throw e; }
} Prevention
- Never let memoized functions return null
- Use explicit defaults or throw descriptive errors in the wrapped function
- Report null-producing paths as harness bugs
When it happens
Trigger: Calling get() on the memoized supplier after f.apply(currentArg) returned null — e.g. a lookup/mapping function used by the timer tracker that fails to find or compute a value.
Common situations: Internal harness code path where a mapping (e.g. from timer id to timer value) unexpectedly yields null due to missing state or a bug; rarely hit directly by users.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- buildDescriptor: couldn't retrieve coder
- cannot encode a null Byte
- cannot encode a null Count-min Sketch
- cannot encode a null Double
- cannot encode a null Float
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d5511d3559e38472.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/state/FnApiTimerBundleTracker.java:227
}
private static <ArgT, ResultT> Supplier<ResultT> memoizeFunction(
Supplier<ArgT> arg, Function<ArgT, ResultT> f) {
return new Supplier<ResultT>() {
private @Nullable ArgT memoizedArg = null;
private @Nullable ResultT memoizedResult = null;
@Override
public ResultT get() {
ArgT currentArg = arg.get();
if (memoizedArg == null || currentArg != memoizedArg) {
this.memoizedArg = currentArg;
memoizedResult = f.apply(currentArg);
}
if (memoizedResult != null) {
return memoizedResult;
} else {
throw new RuntimeException("Unexpected null result.");
}
}
};
}
}
View on GitHub (pinned to 12126d8942)