apache/flink · error · IllegalStateException

Cannot retrieve Right value on a Left

Error message

Cannot retrieve Right value on a Left

What it means

Either is Flink's disjoint-union type with subclasses Left and Right. Left.right() always throws IllegalStateException('Cannot retrieve Right value on a Left') because a Left instance carries no right value; the value is a required non-null field set in the constructor.

Source

Thrown at flink-core/src/main/java/org/apache/flink/types/Either.java:101

     * @param <R> the type of Right
     */
    public static class Left<L, R> extends Either<L, R> {
        private L value;

        private Right<L, R> right;

        public Left(L value) {
            this.value = java.util.Objects.requireNonNull(value);
        }

        @Override
        public L left() {
            return value;
        }

        @Override
        public R right() {
            throw new IllegalStateException("Cannot retrieve Right value on a Left");
        }

        /**
         * Sets the encapsulated value to another value
         *
         * @param value the new value of the encapsulated value
         */
        public void setValue(L value) {
            this.value = value;
        }

        @Override
        public boolean equals(Object object) {
            if (object instanceof Left<?, ?>) {
                final Left<?, ?> other = (Left<?, ?>) object;
                return value.equals(other.value);
            }
            return false;

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Check the side before unwrapping: if (either.isRight()) { R v = either.right(); } else { L l = either.left(); }.
  2. Handle both branches explicitly — Left very often models an error/miss case that must not be silently dropped.
  3. Prefer Flink's ifLeft/ifRight lambdas (when available) or Java's Optional-returning helpers to force branch handling.

Example fix

// before
String v = either.right(); // IllegalStateException when element is a Left

// after
if (either.isRight()) {
    String v = either.right();
} else {
    Throwable err = either.left();
    // handle failure case
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (either.isRight()) {
    String v = either.right();
} else {
    Throwable err = either.left();
}

Type guard

static <L, R> boolean hasRight(Either<L, R> e) {
    return e.isRight(); // true only when safe to call e.right()
}

Prevention

When it happens

Trigger: Calling either.right() on an instance that is a Left — i.e. consuming the value without first checking which side is present (either.isLeft() / either.isRight()).

Common situations: Iterating a heterogeneous result collection where some elements are Left (e.g. failures/misses) and unconditionally calling right(); code written against the happy path where all elements were Right; Scala/Java interop where pattern matching was skipped.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/aeb9c43707614c99. Report an issue: GitHub.