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

  1. Ensure the wrapped function never returns null (return a sentinel/Optional-compatible value).
  2. Check why the underlying computation produced null — usually missing state for the queried key.
  3. Upgrade Beam; this is an internal invariant and a null here indicates a harness bug.
  4. 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

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


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)