{"record":{"id":"7ace57a3c1e2ace2","repo":"apache/flink","slug":"the-binary-operation-has-no-first-input","errorCode":null,"errorMessage":"The binary operation {} has no first input.","messagePattern":"The binary operation (.+?) has no first input\\.","errorType":"validation","errorClass":"InvalidProgramException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/CollectionExecutor.java","lineNumber":283,"sourceCode":"                    operator.getBroadcastInputs().entrySet()) {\n                List<?> bcData = execute(bcInputs.getValue(), jobInfo);\n                ctx.setBroadcastVariable(bcInputs.getKey(), bcData);\n            }\n        } else {\n            ctx = null;\n        }\n\n        return typedOp.executeOnCollections(inputData, ctx, executionConfig);\n    }\n\n    private <IN1, IN2, OUT> List<OUT> executeBinaryOperator(\n            DualInputOperator<?, ?, ?, ?> operator, int superStep, JobInfo jobInfo)\n            throws Exception {\n        Operator<?> inputOp1 = operator.getFirstInput();\n        Operator<?> inputOp2 = operator.getSecondInput();\n\n        if (inputOp1 == null) {\n            throw new InvalidProgramException(\n                    \"The binary operation \" + operator.getName() + \" has no first input.\");\n        }\n        if (inputOp2 == null) {\n            throw new InvalidProgramException(\n                    \"The binary operation \" + operator.getName() + \" has no second input.\");\n        }\n\n        // compute inputs\n        @SuppressWarnings(\"unchecked\")\n        List<IN1> inputData1 = (List<IN1>) execute(inputOp1, superStep, jobInfo);\n        @SuppressWarnings(\"unchecked\")\n        List<IN2> inputData2 = (List<IN2>) execute(inputOp2, superStep, jobInfo);\n\n        @SuppressWarnings(\"unchecked\")\n        DualInputOperator<IN1, IN2, OUT, ?> typedOp =\n                (DualInputOperator<IN1, IN2, OUT, ?>) operator;\n\n        // build the runtime context and compute broadcast variables, if necessary","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/CollectionExecutor.java#L265-L301","documentation":"Thrown by CollectionExecutor.executeBinaryOperator() when operator.getFirstInput() returns null for a DualInputOperator (e.g., JoinOperator, CoGroupOperator, CrossOperator). Binary operators require two inputs; if the first (left) input is null, the operator cannot execute. This is an InvalidProgramException indicating an incomplete join/cogroup/cross plan.","triggerScenarios":"A DualInputOperator (join, cogroup, cross, etc.) is created where the left input DataSet is null. In the high-level API this occurs when the first argument to .join()/.cogroup()/.crossWithHuge() is null or was never set.","commonSituations":"A left-input DataSet variable is null due to an upstream assignment bug, conditional logic that skipped the assignment, or a transformation that unexpectedly returned null. Common in complex pipelines where join inputs are computed conditionally.","solutions":["Verify the left input DataSet is non-null before calling .join()/.cogroup()/.cross().","Inspect the execution plan (env.createPlanAsJSON()) to confirm the first input of each binary operator is wired.","Trace the left input variable's assignment path for null-returning transformations or missed assignments."],"exampleFix":"// before — leftInput is null\nDataSet<Tuple2> leftInput = null;\nleftInput.join(rightInput).where(0).equalTo(0);\n// after\nDataSet<Tuple2> leftInput = env.fromElements(Tuple2.of(1, \"a\"));\nleftInput.join(rightInput).where(0).equalTo(0);","handlingStrategy":"validation","validationCode":"// Verify left input is non-null before join/cogroup/cross\nif (leftInput == null) {\n    throw new IllegalStateException(\"Left input for join is null\");\n}\nleftInput.join(rightInput).where(0).equalTo(0);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate both join inputs are non-null before calling .join()/.cogroup()/.cross().","Check the plan to confirm every DualInputOperator has both inputs wired.","Trace left-input variable assignment paths for null-returning transformations."],"tags":["binary-operator","join","plan-validation","collection-executor","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}