{"record":{"id":"9adb9e08d551f96e","repo":"apache/beam","slug":"key-field-type-should-be-string-but-was-s","errorCode":null,"errorMessage":"key field type should be STRING but was %s","messagePattern":"key field type should be STRING but was (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigtable/BigtableTable.java","lineNumber":162,"sourceCode":"              List<String> pair = Splitter.on(\":\").splitToList(colonSeparatedValues);\n              columnsMapping.putIfAbsent(pair.get(0), newHashSet());\n              columnsMapping.get(pair.get(0)).add(pair.get(1));\n            });\n    return columnsMapping;\n  }\n\n  private static String getMatcherValue(Matcher matcher, String field) {\n    String value = matcher.group(field);\n    return value == null ? \"\" : value;\n  }\n\n  private static void validateSchema(Schema schema) {\n    if (!schema.hasField(KEY)) {\n      throw new IllegalStateException(String.format(\"Schema has to contain '%s' field\", KEY));\n    } else {\n      Schema.Field keyField = schema.getField(KEY);\n      if (keyField != null && !(Schema.TypeName.STRING == keyField.getType().getTypeName())) {\n        throw new IllegalArgumentException(\n            \"key field type should be STRING but was \" + keyField.getType().getTypeName());\n      }\n    }\n  }\n\n  private static void validateMatcher(Matcher matcher, String location) {\n    if (!matcher.matches()) {\n      throw new InvalidTableException(\n          \"Bigtable location must be in the following format:\"\n              + \" 'googleapis.com/bigtable/projects/projectId/instances/instanceId/tables/tableId'\"\n              + \" but was: \"\n              + location);\n    }\n  }\n\n  private static void validateColumnsMapping(\n      Map<String, Set<String>> columnsMapping, Schema schema) {\n    validateColumnsMappingCount(columnsMapping, schema);","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigtable/BigtableTable.java#L144-L180","documentation":"Beyond existing, the mandatory 'key' field must be of type STRING because Bigtable row keys are byte strings. validateSchema throws IllegalArgumentException when the 'key' field's type name is anything other than STRING.","triggerScenarios":"Declaring a Bigtable external table whose 'key' field is INT64, BYTES, or any non-STRING type; the constructor's validateSchema rejects it immediately.","commonSituations":"Copying a schema from a warehouse table where the key is an integer; letting type inference derive key as INT64; changing the key type after a schema refactor.","solutions":["Declare the 'key' field as STRING in the schema.","Cast the source key to STRING in the feeding query/pipeline before writing (e.g. CAST(id AS VARCHAR)).","If byte keys are required, encode them as (UTF-8) strings in the schema and use string values in the pipeline."],"exampleFix":"-- before\nCREATE EXTERNAL TABLE bt (key INT64, cf_val STRING) TYPE 'bigtable' LOCATION '...';\n\n-- after\nCREATE EXTERNAL TABLE bt (key STRING, cf_val STRING) TYPE 'bigtable' LOCATION '...';","handlingStrategy":"type-guard","validationCode":"Schema.Field keyField = schema.getField(\"key\");\nif (keyField != null && keyField.getType().getTypeName() != Schema.TypeName.STRING) {\n  throw new IllegalArgumentException(\"'key' must be STRING, got \" + keyField.getType().getTypeName());\n}","typeGuard":"boolean keyIsString(Schema s) {\n  Schema.Field f = s.getField(\"key\");\n  return f != null && Schema.TypeName.STRING == f.getType().getTypeName();\n}","tryCatchPattern":"try {\n  BigtableTable t = new BigtableTable(table);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"key field type should be STRING\")) {\n    // fix the schema type of 'key' to STRING\n  }\n}","preventionTips":["Always declare key as STRING; cast integer/byte keys with CAST(... AS VARCHAR) upstream.","Avoid schema auto-inference for Bigtable sources; declare the schema explicitly.","Add a schema unit test asserting key type == STRING for all bigtable table definitions."],"tags":["java","beam-sql","bigtable","schema","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}