{"record":{"id":"0e47d8ee6ed31856","repo":"apache/flink","slug":"this-type-type-cannot-be-used-as-key","errorCode":null,"errorMessage":"This type ({type}) cannot be used as key.","messagePattern":"This type \\((.+?)\\) cannot be used as key\\.","errorType":"exception","errorClass":"InvalidProgramException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java","lineNumber":343,"sourceCode":"                    for (FlatFieldDescriptor field : flatFields) {\n                        if (!field.getType().isKeyType()) {\n                            throw new InvalidProgramException(\n                                    \"This type (\" + field.getType() + \") cannot be used as key.\");\n                        }\n                    }\n                    // add flat fields to key fields\n                    keyFields.addAll(flatFields);\n\n                    String strippedKeyExpr = WILD_CARD_REGEX.matcher(keyExpr).replaceAll(\"\");\n                    if (strippedKeyExpr.isEmpty()) {\n                        this.originalKeyTypes[i] = type;\n                    } else {\n                        this.originalKeyTypes[i] = cType.getTypeAt(strippedKeyExpr);\n                    }\n                }\n            } else {\n                if (!type.isKeyType()) {\n                    throw new InvalidProgramException(\n                            \"This type (\" + type + \") cannot be used as key.\");\n                }\n\n                // check that all key expressions are valid\n                for (String keyExpr : keyExpressions) {\n                    if (keyExpr == null) {\n                        throw new InvalidProgramException(\"Expression key may not be null.\");\n                    }\n                    // strip off whitespace\n                    keyExpr = keyExpr.trim();\n                    // check that full type is addressed\n                    if (!(SELECT_ALL_CHAR.equals(keyExpr)\n                            || SELECT_ALL_CHAR_SCALA.equals(keyExpr))) {\n                        throw new InvalidProgramException(\n                                \"Field expression must be equal to '\"\n                                        + SELECT_ALL_CHAR\n                                        + \"' or '\"\n                                        + SELECT_ALL_CHAR_SCALA","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java#L325-L361","documentation":"Thrown by Keys.ExpressionKeys(String[], TypeInformation) in the else-branch where the data type is NOT a CompositeType. For atomic/non-composite types the entire type must itself satisfy isKeyType(). If the type is both non-composite and non-key-type (e.g. a raw Object, a byte array, or a GenericTypeInfo wrapping an unrecognised class), no key can be extracted at all.","triggerScenarios":"Passing a non-composite, non-key type such as ObjectType, a raw array, or a GenericTypeInfo to ExpressionKeys with a field expression. Calling keyBy on a DataStream<SomeRandomClass> where SomeRandomClass is neither a recognised POJO/Tuple nor itself a valid key type.","commonSituations":"Using DataStream<MyDomainObject> without registering type info, so Flink treats it as GenericTypeInfo. Attempting to use an opaque/third-party Java object directly as a key without a KeySelector.","solutions":["Wrap the value in a Tuple1 or a properly-annotated POJO and keyBy on the inner field.","Supply a KeySelector<T, K> to keyBy that extracts a primitive/String key from the object.","Register a TypeInfoFactory for the class so Flink recognises it as a composite or key type.","Avoid using byte[], Object[], or raw generics as keys; convert to a comparable wrapper first."],"exampleFix":"// before\nDataStream<MyObject> ds = ...;\nds.keyBy(\"*\");  // MyObject is GenericTypeInfo → not key type\n\n// after\nds.keyBy(obj -> obj.getId());  // KeySelector extracting a String","handlingStrategy":"type-guard","validationCode":"if (!(type instanceof CompositeType) && !type.isKeyType()) {\n    throw new IllegalArgumentException(\n        \"Type \" + type + \" is neither composite nor a valid key type.\");\n}","typeGuard":"static boolean canBeUsedAsKey(TypeInformation<?> type) {\n    return (type instanceof CompositeType) || type.isKeyType();\n}","tryCatchPattern":"try {\n    new Keys.ExpressionKeys<>(exprs, type);\n} catch (InvalidProgramException e) {\n    if (e.getMessage().contains(\"cannot be used as key\")) {\n        ds.keyBy(new KeySelector<T,String>(){ ... });\n    } else throw e;\n}","preventionTips":["Prefer KeySelector over field-expression keyBy for opaque/generic types.","Register TypeInfoFactories for custom domain classes.","Avoid using raw Object or arrays as stream element types."],"tags":["keys","type-system","keyby","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}