{"record":{"id":"b2274c27cd3791ca","repo":"apache/flink","slug":"expression-key-may-not-be-null","errorCode":null,"errorMessage":"Expression key may not be null.","messagePattern":"Expression key may not be null\\.","errorType":"exception","errorClass":"InvalidProgramException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java","lineNumber":310,"sourceCode":"            this(new String[] {keyExpression}, type);\n        }\n\n        /** Create String-based (nested) field expression keys on a composite type. */\n        public ExpressionKeys(String[] keyExpressions, TypeInformation<T> type) {\n            checkNotNull(keyExpressions, \"Field expression cannot be null.\");\n\n            this.keyFields = new ArrayList<>(keyExpressions.length);\n\n            if (type instanceof CompositeType) {\n                CompositeType<T> cType = (CompositeType<T>) type;\n                this.originalKeyTypes = new TypeInformation<?>[keyExpressions.length];\n\n                // extract the keys on their flat position\n                for (int i = 0; i < keyExpressions.length; i++) {\n                    String keyExpr = keyExpressions[i];\n\n                    if (keyExpr == null) {\n                        throw new InvalidProgramException(\"Expression key may not be null.\");\n                    }\n                    // strip off whitespace\n                    keyExpr = keyExpr.trim();\n\n                    List<FlatFieldDescriptor> flatFields = cType.getFlatFields(keyExpr);\n\n                    if (flatFields.size() == 0) {\n                        throw new InvalidProgramException(\n                                \"Unable to extract key from expression '\"\n                                        + keyExpr\n                                        + \"' on key \"\n                                        + cType);\n                    }\n                    // check if all nested fields can be used as keys\n                    for (FlatFieldDescriptor field : flatFields) {\n                        if (!field.getType().isKeyType()) {\n                            throw new InvalidProgramException(\n                                    \"This type (\" + field.getType() + \") cannot be used as key.\");","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java#L292-L328","documentation":"Thrown by ExpressionKeys(String[], TypeInformation) when one of the key expression strings is null. Field-expression keys like groupBy(\"userId\") must each be a non-null string; a null entry (often from a list with a gap) cannot be resolved against the type.","triggerScenarios":"Passing a String[] with a null element to ExpressionKeys or groupBy(String...); building key expressions from a Map whose get() returned null for some field; array initialisation that left a slot null.","commonSituations":"Programmatic field lists with optional entries that defaulted to null; config-driven field names where one key was missing; refactors that introduced a null into a previously all-literal list.","solutions":["Filter or reject null entries from the key-expression array before use.","Use a List<String> and removeIf(Objects::isNull), or validate at the source.","Fail fast with a clear error naming which configured field is missing."],"exampleFix":"// before\nString[] keys = {\"a\", config.get(\"b\"), \"c\"}; // config.get(\"b\") may be null\nds.groupBy(keys);\n// after\nList<String> keys = new ArrayList<>(Arrays.asList(\"a\", config.get(\"b\"), \"c\"));\nkeys.removeIf(Objects::isNull);\nds.groupBy(keys.toArray(new String[0]));","handlingStrategy":"validation","validationCode":"for (String e : keyExpressions) {\n    if (e == null) throw new IllegalArgumentException(\"Key expression must not be null\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter nulls from programmatic field lists before passing them as keys.","Use List.removeIf(Objects::isNull) or validate at the source.","Fail fast at the config layer when a required field name is missing."],"tags":["flink-core","keys","expression-keys","null-check","validation"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}