{"record":{"id":"b9e423f51a9226e1","repo":"apache/flink","slug":"the-type-cannot-be-used-as-a-key","errorCode":null,"errorMessage":"The type {} cannot be used as a key.","messagePattern":"The type (.+?) cannot be used as a key\\.","errorType":"exception","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/typeinfo/BasicTypeInfo.java","lineNumber":251,"sourceCode":"    @PublicEvolving\n    public boolean isKeyType() {\n        return true;\n    }\n\n    @Override\n    @PublicEvolving\n    public TypeSerializer<T> createSerializer(SerializerConfig serializerConfig) {\n        return this.serializer;\n    }\n\n    @Override\n    @PublicEvolving\n    public TypeComparator<T> createComparator(\n            boolean sortOrderAscending, ExecutionConfig executionConfig) {\n        if (comparatorClass != null) {\n            return instantiateComparator(comparatorClass, sortOrderAscending);\n        } else {\n            throw new InvalidTypesException(\n                    \"The type \" + clazz.getSimpleName() + \" cannot be used as a key.\");\n        }\n    }\n\n    // --------------------------------------------------------------------------------------------\n\n    @Override\n    public int hashCode() {\n        return (31 * Objects.hash(clazz, serializer, comparatorClass))\n                + Arrays.hashCode(possibleCastTargetTypes);\n    }\n\n    @Override\n    public boolean canEqual(Object obj) {\n        return obj instanceof BasicTypeInfo;\n    }\n\n    @Override","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/typeinfo/BasicTypeInfo.java#L233-L269","documentation":"BasicTypeInfo.createComparator returns a TypeComparator only when comparatorClass is non-null. Some basic types (e.g., Void) have a null comparatorClass because they are not orderable, so attempting to build a comparator for them throws InvalidTypesException saying the type cannot be used as a key. This is the key-eligibility gate for basic types.","triggerScenarios":"Using a basic type with no comparator as a key (keyBy, joining, grouping, windowing on that field); calling createComparator directly on a BasicTypeInfo whose comparatorClass is null; keying a stream by a Void-typed field.","commonSituations":"keyBy on a field whose type resolves to a non-comparable basic type; schema changes that make a previously-keyed field nullable/void; generic code that builds comparators for arbitrary TypeInformation without checking isKeyType().","solutions":["Choose a key field whose TypeInformation.isKeyType() returns true (orderable types like String, Integer, Long).","Avoid keying on Void or other non-orderable basic types; restructure the pipeline to use a concrete comparable key.","Guard generic comparator-building code with typeInfo.isKeyType() before calling createComparator."],"exampleFix":"// before\ndataStream.keyBy(e -> null); // Void key -> throws\n\n// after\ndataStream.keyBy(Event::getId); // Long key, orderable","handlingStrategy":"type-guard","validationCode":"TypeInformation<?> keyTi = TypeInformation.of(keyClass);\nif (!keyTi.isKeyType()) {\n    throw new IllegalArgumentException(keyTi + \" cannot be used as a key\");\n}","typeGuard":"static boolean isUsableAsKey(TypeInformation<?> ti) {\n    return ti.isKeyType();\n}","tryCatchPattern":"// Prefer keyBy with a properly typed key selector; avoid catching createComparator.\n// If building comparators generically:\ntry {\n    return ti.createComparator(asc, cfg);\n} catch (InvalidTypesException e) {\n    throw new IllegalArgumentException(ti + \" is not key-comparable\", e);\n}","preventionTips":["Always keyBy on orderable types (primitives, String, Date, Tuple of orderables).","Guard generic comparator code with typeInfo.isKeyType().","Avoid Void or non-orderable fields as keys."],"tags":["type-information","comparator","key-type","keyby"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}