{"record":{"id":"f9d3de3d00a21df5","repo":"apache/beam","slug":"keyfield-property-cannot-be-null","errorCode":null,"errorMessage":"'keyField' property cannot be null.","messagePattern":"'keyField' property cannot be null\\.","errorType":"validation","errorClass":"InvalidConfigurationException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/datastore/DataStoreV1SchemaIOProvider.java","lineNumber":160,"sourceCode":"        public POutput expand(PCollection<Row> input) {\n          return input\n              .apply(\"Convert Rows to Datastore Entities\", RowToEntity.create(keyField, kind))\n              .apply(\"Write Datastore Entities\", DatastoreIO.v1().write().withProjectId(projectId));\n        }\n      };\n    }\n\n    public String getProjectId() {\n      return projectId;\n    }\n\n    public String getKind() {\n      return kind;\n    }\n\n    private String determineKeyField(String configKey) {\n      if (configKey != null && configKey.isEmpty()) {\n        throw new InvalidConfigurationException(\n            String.format(\"'%s' property cannot be null.\", KEY_FIELD_PROPERTY));\n      } else if (configKey != null) {\n        return configKey;\n      } else {\n        return DEFAULT_KEY_FIELD;\n      }\n    }\n\n    private void validateLocation(String location, Matcher matcher) {\n      // TODO: allow users to specify a namespace in a location string.\n      if (location == null) {\n        throw new InvalidLocationException(\"DataStoreV1 location must be set. \");\n      }\n      if (!matcher.matches()) {\n        throw new InvalidLocationException(\n            \"DataStoreV1 location must be in the following format: 'projectId/kind'\"\n                + \" but was:\"\n                + location);","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/datastore/DataStoreV1SchemaIOProvider.java#L142-L178","documentation":"DataStoreV1SchemaIOProvider.determineKeyField validates the 'keyField' configuration property. Because the check tests `configKey != null && configKey.isEmpty()`, an explicitly-set-but-empty keyField throws InvalidConfigurationException \"'keyField' property cannot be null.\"; a non-empty value is returned as-is and null falls back to DEFAULT_KEY_FIELD (typically \"__key__\").","triggerScenarios":"Specifying location 'project/kind' with an empty keyField option, e.g. --keyField= or withSchemaIO keyField:\"\" when creating a DataStoreV1 sink/source via SchemaIO.","commonSituations":"Templated/parameterized pipelines where a parameter resolves to empty string; shell scripts passing an unset variable into the keyField option; copy-pasted config with the value deleted.","solutions":["Remove the keyField option entirely to use the default key field (Datastore entity __key__).","Provide a real property name as keyField, e.g. --keyField=id.","If it comes from a parameter/variable, ensure it is either unset or has a non-empty value."],"exampleFix":"// before\n--keyField= \n// after\n--keyField=id   (or omit the flag to use the default __key__)","handlingStrategy":"validation","validationCode":"if (keyFieldOption != null && keyFieldOption.isEmpty()) {\n  throw new IllegalArgumentException(\"--keyField must be a non-empty property name, or omitted entirely.\");\n}","typeGuard":"static String sanitizeKeyField(String keyField) {\n  return (keyField == null || keyField.isEmpty()) ? null /* fall back to default __key__ */ : keyField;\n}","tryCatchPattern":"try {\n  DataStoreV1SchemaIO io = (DataStoreV1SchemaIO) DataStoreV1SchemaIOProvider.schemaIO(location, config);\n} catch (InvalidConfigurationException e) {\n  // rebuild config without keyField to use the default key field\n}","preventionTips":["Omit the keyField option when you want the default (__key__) behavior — do not pass an empty string.","Validate templated parameters resolve to non-empty values before launching.","In scripts, guard variable substitution: only pass --keyField when the variable is set."],"tags":["datastore","configuration","empty-value","java"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}