{"record":{"id":"14f229acdf1a2e24","repo":"apache/beam","slug":"unsupported-logical-type-in-iterable-s","errorCode":null,"errorMessage":"Unsupported logical type in iterable: %s","messagePattern":"Unsupported logical type in iterable: (.+?)","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/MutationUtils.java","lineNumber":391,"sourceCode":"        break;\n      case LOGICAL_TYPE:\n        String identifier = checkNotNull(beamIterableType.getLogicalType()).getIdentifier();\n        if (identifier.equals(MicrosInstant.IDENTIFIER)) {\n          if (iterable == null) {\n            mutationBuilder.set(column).toTimestampArray(null);\n          } else {\n            mutationBuilder\n                .set(column)\n                .toTimestampArray(\n                    StreamSupport.stream(iterable.spliterator(), false)\n                        .map(\n                            instant -> {\n                              return toSpannerTimestamp((java.time.Instant) instant);\n                            })\n                        .collect(toList()));\n          }\n        } else {\n          throw new IllegalArgumentException(\n              String.format(\"Unsupported logical type in iterable: %s\", identifier));\n        }\n        break;\n      case DATETIME:\n        if (iterable == null) {\n          mutationBuilder.set(column).toDateArray(null);\n        } else {\n          mutationBuilder\n              .set(column)\n              .toTimestampArray(\n                  StreamSupport.stream(iterable.spliterator(), false)\n                      .map(datetime -> Timestamp.parseTimestamp(datetime.toString()))\n                      .collect(toList()));\n        }\n        break;\n      default:\n        throw new IllegalArgumentException(\n            String.format(","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationUtils.java#L373-L409","documentation":"Inside addIterableToMutationBuilder, an iterable whose element type is a LOGICAL_TYPE with an identifier the translator does not recognize reaches the LOGICAL_TYPE case. Only specific logical identifiers (e.g. java.lang.Instant with the toSpannerTimestamp mapping) are supported; anything else throws IllegalArgumentException.","triggerScenarios":"An ITERABLE field whose element type is Schema.FieldType.logicalType with an identifier other than the supported ones (e.g. a custom LogicalType like a bespoke enum or decimal logical type) is written to Spanner.","commonSituations":"Users define custom Beam LogicalTypes (money, json, custom enums) and try to write arrays of them to Spanner; Beam version changes add new built-in logical types not yet mapped by the Spanner IO.","solutions":["Map the custom logical type to a supported base type (STRING, INT64, etc.) before writing, e.g. via a Map converting elements to their portable representation.","Check the identifier printed in the message against the supported list in MutationUtils and align your logical type identifier.","Upgrade Beam if a newer version supports the logical type, or contribute a mapping case."],"exampleFix":"// before: iterable of custom logical type\nrows.apply(SpannerIO.write()...)\n// after: convert to supported base type first\nPCollection<Row> converted = rows.apply(MapElements.into(...).via(r -> /* convert custom logical type values to String/int64 fields */ r));","handlingStrategy":"validation","validationCode":"Schema.FieldType el = field.getType().getCollectionElementType();\nif (el != null && el.getTypeName() == Schema.TypeName.LOGICAL_TYPE) {\n  String id = el.getLogicalType().getIdentifier();\n  if (!java.util.Set.of(\"Instant\", \"DateTime\", \"LocalDate\").contains(id)) {\n    throw new IllegalStateException(\"Unsupported logical type in iterable: \" + id);\n  }\n}","typeGuard":null,"tryCatchPattern":"try { write.apply(...); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Unsupported logical type in iterable\")) { /* convert to base type */ } else throw e; }","preventionTips":["Use only built-in logical types (Instant, DateTime) for iterable fields written to Spanner","Convert custom LogicalTypes to portable base types upstream","Pin and test with your Beam version; check release notes for new logical types"],"tags":["java","beam","spanner","logical-type","unsupported-type"],"backgroundTag":"unsupported-operation","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"}