{"record":{"id":"25eccc89f6728e79","repo":"apache/beam","slug":"unknown-type-mutationkeyencoder","errorCode":null,"errorMessage":"Unknown type {}","messagePattern":"Unknown type (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationKeyEncoder.java","lineNumber":144,"sourceCode":"            writeString(orderedCode, part, val.getString());\n            break;\n          case BYTES:\n            writeBytes(orderedCode, part, val.getBytes());\n            break;\n          case TIMESTAMP:\n            writeTimestamp(orderedCode, part, val.getTimestamp());\n            break;\n          case DATE:\n            writeNumber(orderedCode, part, encodeDate(val.getDate()));\n            break;\n          case NUMERIC:\n            writeString(orderedCode, part, val.getNumeric().toString());\n            break;\n          case JSON:\n            writeString(orderedCode, part, val.getJson());\n            break;\n          default:\n            throw new IllegalArgumentException(\"Unknown type \" + val.getType());\n        }\n      }\n    }\n  }\n\n  private void encodeKey(OrderedCode orderedCode, String tableName, Key key) {\n    List<SpannerSchema.KeyPart> parts = schema.getKeyParts(tableName);\n    Iterator<Object> it = key.getParts().iterator();\n    for (SpannerSchema.KeyPart part : parts) {\n      Object value = it.next();\n      if (value == null) {\n        if (part.isDesc()) {\n          orderedCode.writeInfinityDecreasing();\n        } else {\n          orderedCode.writeInfinity();\n        }\n      } else {\n        if (value instanceof Boolean) {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationKeyEncoder.java#L126-L162","documentation":"MutationKeyEncoder.encodeKey() maps each Spanner Key value's Type code to an ordered-code writer. When a key column has a Type code that the encoder does not handle (e.g. STRUCT or other non-scalar types used as key), the default branch throws IllegalArgumentException('Unknown type ...'). Spanner primary keys only support scalar types, so this indicates a non-scalar or newly added type reached the encoder.","triggerScenarios":"Writing to a Cloud Spanner table whose primary key column is of a type the encoder lacks a case for (e.g. STRUCT, or a newer Spanner type when running an older Beam version); the type comes from the actual key Value in the mutation.","commonSituations":"Spanner schema has an unusual key column type; Beam/google-cloud-spanner library version mismatch introduces a Type code the Beam encoder doesn't know; reading from one Spanner DB and writing to another with a different key schema.","solutions":["Ensure the table's primary key uses supported scalar types (STRING, INT64, FLOAT64, BOOL, TIMESTAMP, DATE, NUMERIC, JSON, BYTES).","Upgrade the Beam google-cloud-platform SDK so the encoder recognizes newer Spanner Type codes.","Re-map your mutation to encode the offending column into a supported scalar before writing."],"exampleFix":"// before: key column is STRUCT/ARRAY — not encodable\n// after: use a scalar STRING key column, or hash the composite value into a STRING key","handlingStrategy":"validation","validationCode":"for (Value v : key.values()) {\n  if (!Set.of(\"STRING\",\"INT64\",\"FLOAT64\",\"BOOL\",\"TIMESTAMP\",\"DATE\",\"NUMERIC\",\"JSON\",\"BYTES\").contains(v.getType().getCode().name()))\n    throw new IllegalArgumentException(\"unsupported key type: \" + v.getType());\n}","typeGuard":"boolean isEncodableKeyType(Type t) { return t.getCode() != Type.Code.STRUCT && t.getCode() != Type.Code.ARRAY; }","tryCatchPattern":"try { writeResult = pipeline.apply(SpannerIO.write()...) } catch (IllegalArgumentException e) { /* fix key schema */ }","preventionTips":["Keep Spanner primary keys to scalar column types only","Keep Beam and google-cloud-spanner versions in sync","Validate target table DDL before deploying a write pipeline"],"tags":["java","apache-beam","spanner","type-mismatch"],"backgroundTag":"unsupported-enum-value","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"}