apache/flink · error · IllegalStateException

Cannot retrieve Left value on a Right

Error message

Cannot retrieve Left value on a Right

What it means

The dual of Left.right(): Either.Right.left() always throws IllegalStateException('Cannot retrieve Left value on a Right') because a Right instance carries no left value. The Right value itself is a required non-null field; only left() is unavailable.

Source

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

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

        private Left<L, R> left;

        public Right(R value) {
            this.value = java.util.Objects.requireNonNull(value);
        }

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

        @Override
        public R right() {
            return value;
        }

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

        @Override
        public boolean equals(Object object) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Check the side first: if (either.isLeft()) { L err = either.left(); } else { R ok = either.right(); }.
  2. Ensure success (Right) values are consumed rather than assuming failure — the exception is a signal that the unhandled branch occurred.
  3. Where the convention is 'Left = failure', centralize unwrapping in one helper that always branches on isLeft()/isRight().

Example fix

// before
Throwable err = either.left(); // IllegalStateException when element is a Right

// after
if (either.isLeft()) {
    Throwable err = either.left();
    // handle failure
} else {
    String ok = either.right();
    // handle success
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (either.isLeft()) {
    Throwable err = either.left();
} else {
    String ok = either.right();
}

Type guard

static <L, R> boolean hasLeft(Either<L, R> e) {
    return e.isLeft(); // true only when safe to call e.left()
}

Prevention

When it happens

Trigger: Calling either.left() on an instance that is a Right — consuming the failure/alternative channel without first verifying with either.isLeft() that it is present.

Common situations: Error-handling code that assumes every Either is a Left after a partial failure, but some elements succeeded (Right); mixed success/failure batches where the success path is not handled; refactoring that swapped the meaning of Left/Right without updating consumers.

Related errors


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