{"record":{"id":"5018eafa8e500ec2","repo":"apache/flink","slug":"a-flattened-field-can-not-be-a-composite-type","errorCode":null,"errorMessage":"A flattened field can not be a composite type","messagePattern":"A flattened field can not be a composite type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/typeutils/CompositeType.java","lineNumber":208,"sourceCode":"    // --------------------------------------------------------------------------------------------\n\n    @PublicEvolving\n    protected interface TypeComparatorBuilder<T> {\n        void initializeTypeComparatorBuilder(int size);\n\n        void addComparatorField(int fieldId, TypeComparator<?> comparator);\n\n        TypeComparator<T> createTypeComparator(ExecutionConfig config);\n    }\n\n    @PublicEvolving\n    public static class FlatFieldDescriptor {\n        private int keyPosition;\n        private TypeInformation<?> type;\n\n        public FlatFieldDescriptor(int keyPosition, TypeInformation<?> type) {\n            if (type instanceof CompositeType) {\n                throw new IllegalArgumentException(\"A flattened field can not be a composite type\");\n            }\n            this.keyPosition = keyPosition;\n            this.type = type;\n        }\n\n        public int getPosition() {\n            return keyPosition;\n        }\n\n        public TypeInformation<?> getType() {\n            return type;\n        }\n\n        @Override\n        public String toString() {\n            return \"FlatFieldDescriptor [position=\" + keyPosition + \" typeInfo=\" + type + \"]\";\n        }\n    }","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/typeutils/CompositeType.java#L190-L226","documentation":"Thrown by the FlatFieldDescriptor constructor when the supplied TypeInformation is itself a CompositeType (i.e. Tuple, POJO, Row). A FlatFieldDescriptor represents a fully flattened leaf field, which by definition must be an atomic (non-composite) type. Constructing one with a composite type signals a bug in field-expression resolution.","triggerScenarios":"Internal code or a custom CompositeType subclass calling new FlatFieldDescriptor(pos, compositeTypeInfo). Also triggered when a field expression with a trailing dot or wildcard resolves to a composite type instead of drilling down to an atomic field. This is primarily an internal invariant, not a user-facing API in most cases.","commonSituations":"Implementing a custom CompositeType with a buggy getFlatFields override that stops at a composite field. A field expression like \"nested.\" (trailing dot) or an empty selector on a nested tuple that does not recurse. Flink version mismatch where a custom type's field resolution logic changed.","solutions":["If implementing a custom CompositeType, ensure getFlatFields recurses into nested composite types until only atomic FlatFieldDescriptors remain.","If you are a user hitting this via keyBy or field selectors, check that your field expression targets a leaf field, not a nested composite object.","Avoid selecting a whole nested object as a key; instead select a specific field within it (e.g. 'nested.id' not 'nested')."],"exampleFix":"// before — selecting a nested composite object as a flat key\n// class Outer { Nested nested; }  class Nested { int id; }\nds.keyBy(\"nested\") // resolves to composite Nested -> FlatFieldDescriptor rejects\n\n// after — select the leaf atomic field\nds.keyBy(\"nested.id\") // ok","handlingStrategy":"validation","validationCode":"// If building FlatFieldDescriptor manually, guard against composite types\nTypeInformation<?> fieldType = compositeType.getTypeAt(pos);\nif (fieldType instanceof CompositeType) {\n    throw new IllegalStateException(\n        \"Field at \" + pos + \" is composite; drill into a leaf field instead.\");\n}\nFlatFieldDescriptor desc = new FlatFieldDescriptor(pos, fieldType);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When selecting keys via field expressions, always target leaf atomic fields, not whole nested objects.","If implementing a custom CompositeType, ensure getFlatFields recurses to atomic leaves only."],"tags":["type-system","composite-type","internal-invariant","field-selector"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}