{"record":{"id":"076f837617afe5a0","repo":"apache/flink","slug":"target-field-was-added-twice","errorCode":null,"errorMessage":"Target field {} was added twice.","messagePattern":"Target field (.+?) was added twice\\.","errorType":"exception","errorClass":"InvalidSemanticAnnotationException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/SingleInputSemanticProperties.java","lineNumber":86,"sourceCode":"    @Override\n    public FieldSet getReadFields(int input) {\n        if (input != 0) {\n            throw new IndexOutOfBoundsException();\n        }\n\n        return this.readFields;\n    }\n\n    /**\n     * Adds, to the existing information, a field that is forwarded directly from the source\n     * record(s) to the destination record(s).\n     *\n     * @param sourceField the position in the source record(s)\n     * @param targetField the position in the destination record(s)\n     */\n    public void addForwardedField(int sourceField, int targetField) {\n        if (isTargetFieldPresent(targetField)) {\n            throw new InvalidSemanticAnnotationException(\n                    \"Target field \" + targetField + \" was added twice.\");\n        }\n\n        FieldSet targetFields = fieldMapping.get(sourceField);\n        if (targetFields != null) {\n            fieldMapping.put(sourceField, targetFields.addField(targetField));\n        } else {\n            fieldMapping.put(sourceField, new FieldSet(targetField));\n        }\n    }\n\n    private boolean isTargetFieldPresent(int targetField) {\n        for (FieldSet targetFields : fieldMapping.values()) {\n            if (targetFields.contains(targetField)) {\n                return true;\n            }\n        }\n        return false;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/SingleInputSemanticProperties.java#L68-L104","documentation":"Thrown by SingleInputSemanticProperties.addForwardedField(int sourceField, int targetField) when the targetField position has already been registered as a forwarded target from any source field. The method enforces that each output field is forwarded from exactly one input field; a second mapping to the same target is a contradictory semantic annotation.","triggerScenarios":"Manually calling addForwardedField(0, 1) followed by addForwardedField(2, 1) on the same SingleInputSemanticProperties instance. Using duplicate or overlapping @ForwardedField annotations on a function that the compiler translates into addForwardedField calls.","commonSituations":"Incorrect @ForwardedField annotations on a MapFunction or FlatMapFunction where two input fields are annotated as forwarding to the same output position. Copy-paste errors when annotating a rich function's semantic properties. Misunderstanding positional semantics of forwarded fields.","solutions":["Review the function's @ForwardedField annotations and ensure each target field index appears in exactly one annotation.","If a field is genuinely computed (not forwarded), remove it from @ForwardedField annotations.","If you are manually building SingleInputSemanticProperties, check isTargetFieldPresent(targetField) before calling addForwardedField, or audit the fieldMapping for duplicate targets.","Use @ForwardedFields with correct source->target position expressions."],"exampleFix":"// before\n@ForwardedField(\"0->1; 2->1\") // ERROR: target field 1 twice\npublic static class MyMapper extends RichMapFunction<Tuple3<String, Integer, String>, Tuple2<String, Integer>> {\n    public Tuple2<String, Integer> map(Tuple3<String, Integer, String> in) { ... }\n}\n\n// after\n@ForwardedField(\"0->1\")\npublic static class MyMapper extends RichMapFunction<Tuple3<String, Integer, String>, Tuple2<String, Integer>> {\n    public Tuple2<String, Integer> map(Tuple3<String, Integer, String> in) { ... }\n}","handlingStrategy":"validation","validationCode":"void safeAddForwardedField(SingleInputSemanticProperties props, int source, int target) {\n    if (props instanceof SingleInputSemanticProperties.AllFieldsForwardedProperties) return;\n    // Check if target is already claimed by another source\n    for (int s = 0; s < 256; s++) {\n        if (s != source && props.getForwardingTargetFields(0, s).contains(target)) {\n            throw new IllegalStateException(\"Target field \" + target + \" already forwarded from source \" + s);\n        }\n    }\n    props.addForwardedField(source, target);\n}","typeGuard":"boolean isTargetAvailable(SingleInputSemanticProperties props, int targetField) {\n    return props.getForwardingSourceField(0, targetField) == -1;\n}","tryCatchPattern":"try {\n    props.addForwardedField(sourceField, targetField);\n} catch (InvalidSemanticAnnotationException e) {\n    // duplicate target field annotation; review @ForwardedField annotations\n    throw new RuntimeException(\"Duplicate @ForwardedField target: \" + e.getMessage(), e);\n}","preventionTips":["Audit @ForwardedField annotations to ensure each target position appears exactly once.","Use a helper that checks getForwardingSourceField before addForwardedField.","Write unit tests that validate semantic property consistency before job submission."],"tags":["semantic-properties","forwarded-field","annotation","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}