{"record":{"id":"116aafc1d98af60a","repo":"apache/flink","slug":"the-bulkiteration-meta-operator-cannot-have-broadc","errorCode":null,"errorMessage":"The BulkIteration meta operator cannot have broadcast inputs.","messagePattern":"The BulkIteration meta operator cannot have broadcast inputs\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/base/BulkIterationBase.java","lineNumber":199,"sourceCode":"\n    /**\n     * The BulkIteration meta operator cannot have broadcast inputs.\n     *\n     * @return An empty map.\n     */\n    public Map<String, Operator<?>> getBroadcastInputs() {\n        return Collections.emptyMap();\n    }\n\n    /**\n     * The BulkIteration meta operator cannot have broadcast inputs. This method always throws an\n     * exception.\n     *\n     * @param name Ignored.\n     * @param root Ignored.\n     */\n    public void setBroadcastVariable(String name, Operator<?> root) {\n        throw new UnsupportedOperationException(\n                \"The BulkIteration meta operator cannot have broadcast inputs.\");\n    }\n\n    /**\n     * The BulkIteration meta operator cannot have broadcast inputs. This method always throws an\n     * exception.\n     *\n     * @param inputs Ignored\n     */\n    public <X> void setBroadcastVariables(Map<String, Operator<X>> inputs) {\n        throw new UnsupportedOperationException(\n                \"The BulkIteration meta operator cannot have broadcast inputs.\");\n    }\n\n    // --------------------------------------------------------------------------------------------\n\n    /**\n     * Specialized operator to use as a recognizable place-holder for the input to the step function","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/base/BulkIterationBase.java#L181-L217","documentation":"Thrown by BulkIterationBase.setBroadcastVariable(String, Operator<?>) — this method always throws UnsupportedOperationException. A BulkIteration is a meta-operator that wraps an iteration body; broadcast variables cannot be attached to the iteration itself because the concept does not apply at the meta-operator level. Broadcast variables should be attached to operators within the step function.","triggerScenarios":"Calling iteration.setBroadcastVariable(\"name\", someOperator) on a BulkIterationBase instance. Generic code that iterates over operators and calls setBroadcastVariable on each without checking the operator type.","commonSituations":"Generic visitor or traversal code that treats all operators uniformly and calls setBroadcastVariable on each. Misunderstanding that broadcast variables go on inner operators, not the iteration wrapper. Copy-pasting broadcast setup code across operators including iterations.","solutions":["Do not call setBroadcastVariable on BulkIterationBase; attach broadcast variables to operators within the step function body instead.","Check operator type before calling setBroadcastVariable; skip BulkIterationBase and DeltaIterationBase.","Use getBroadcastInputs() (which returns an empty map) to check before attempting to set.","Refactor generic operator-processing code to handle iteration meta-operators as special cases."],"exampleFix":"// before\nfor (Operator<?> op : allOperators) {\n    op.setBroadcastVariable(\"cache\", broadcastData); // throws for BulkIterationBase\n}\n\n// after\nfor (Operator<?> op : allOperators) {\n    if (!(op instanceof BulkIterationBase) && !(op instanceof DeltaIterationBase)) {\n        op.setBroadcastVariable(\"cache\", broadcastData);\n    }\n    // attach broadcast to operators inside the iteration body separately\n}","handlingStrategy":"type-guard","validationCode":"void safeSetBroadcastVariable(Operator<?> op, String name, Operator<?> bc) {\n    if (op instanceof BulkIterationBase || op instanceof DeltaIterationBase) {\n        throw new UnsupportedOperationException(\n            \"Cannot set broadcast variable on iteration meta-operator: \" + op);\n    }\n    op.setBroadcastVariable(name, bc);\n}","typeGuard":"static boolean canHaveBroadcastInputs(Operator<?> op) {\n    return !(op instanceof BulkIterationBase) && !(op instanceof DeltaIterationBase);\n}","tryCatchPattern":"try {\n    op.setBroadcastVariable(name, bcData);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"meta operator\")) {\n        log.debug(\"Skipping broadcast set on iteration meta-operator {}\", op);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check instanceof BulkIterationBase/DeltaIterationBase before calling setBroadcastVariable.","Attach broadcasts to operators inside the iteration step function, not the iteration itself.","In generic DAG traversal code, handle iteration meta-operators as special cases."],"tags":["bulk-iteration","broadcast-variable","unsupported-operation","dataset-api","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}