{"record":{"id":"47a9c2f958cffa00","repo":"apache/flink","slug":"cannot-retrieve-left-value-on-a-right","errorCode":null,"errorMessage":"Cannot retrieve Left value on a Right","messagePattern":"Cannot retrieve Left value on a Right","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/types/Either.java","lineNumber":155,"sourceCode":"\n    /**\n     * A right value of {@link Either}\n     *\n     * @param <L> the type of Left\n     * @param <R> the type of Right\n     */\n    public static class Right<L, R> extends Either<L, R> {\n        private R value;\n\n        private Left<L, R> left;\n\n        public Right(R value) {\n            this.value = java.util.Objects.requireNonNull(value);\n        }\n\n        @Override\n        public L left() {\n            throw new IllegalStateException(\"Cannot retrieve Left value on a Right\");\n        }\n\n        @Override\n        public R right() {\n            return value;\n        }\n\n        /**\n         * Sets the encapsulated value to another value\n         *\n         * @param value the new value of the encapsulated value\n         */\n        public void setValue(R value) {\n            this.value = value;\n        }\n\n        @Override\n        public boolean equals(Object object) {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/types/Either.java#L137-L173","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the side first: if (either.isLeft()) { L err = either.left(); } else { R ok = either.right(); }.","Ensure success (Right) values are consumed rather than assuming failure — the exception is a signal that the unhandled branch occurred.","Where the convention is 'Left = failure', centralize unwrapping in one helper that always branches on isLeft()/isRight()."],"exampleFix":"// before\nThrowable err = either.left(); // IllegalStateException when element is a Right\n\n// after\nif (either.isLeft()) {\n    Throwable err = either.left();\n    // handle failure\n} else {\n    String ok = either.right();\n    // handle success\n}","handlingStrategy":"type-guard","validationCode":"if (either.isLeft()) {\n    Throwable err = either.left();\n} else {\n    String ok = either.right();\n}","typeGuard":"static <L, R> boolean hasLeft(Either<L, R> e) {\n    return e.isLeft(); // true only when safe to call e.left()\n}","tryCatchPattern":null,"preventionTips":["Check isLeft() before left(); a Right means success and must be consumed instead.","Centralize Either unwrapping in helpers that always branch on both sides.","Keep the Left/Right convention consistent across the codebase to avoid swapped consumers."],"tags":["types","either","flink-core","api-misuse"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}