{"record":{"id":"c38e182d4534466a","repo":"apache/beam","slug":"invalid-array-type-originalspannertype","errorCode":null,"errorMessage":"Invalid ARRAY type: + originalSpannerType","messagePattern":"Invalid ARRAY type: \\+ originalSpannerType","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/SpannerSchema.java","lineNumber":223,"sourceCode":"            return Type.string();\n          }\n          if (spannerType.startsWith(\"BYTES\")) {\n            return Type.bytes();\n          }\n          if (spannerType.startsWith(\"ARRAY\")) {\n            // find 'xxx' in string ARRAY<xxxxx>\n            // Graph DBs may have suffixes, eg ARRAY<FLOAT32>(vector_length=>256)\n            //\n            Pattern pattern = Pattern.compile(\"ARRAY<([^>]+)>\");\n            Matcher matcher = pattern.matcher(originalSpannerType);\n\n            if (matcher.find()) {\n              String spannerArrayType = matcher.group(1).trim();\n              Type itemType = parseSpannerType(spannerArrayType, dialect);\n              return Type.array(itemType);\n            } else {\n              // Handle the case where the regex doesn't match (invalid ARRAY type)\n              throw new IllegalArgumentException(\"Invalid ARRAY type: \" + originalSpannerType);\n            }\n          }\n          if (spannerType.startsWith(\"PROTO\")) {\n            // Substring \"PROTO<xxx>\"\n            String spannerProtoType =\n                originalSpannerType.substring(6, originalSpannerType.length() - 1);\n            return Type.proto(spannerProtoType);\n          }\n          if (spannerType.startsWith(\"ENUM\")) {\n            // Substring \"ENUM<xxx>\"\n            String spannerEnumType =\n                originalSpannerType.substring(5, originalSpannerType.length() - 1);\n            return Type.protoEnum(spannerEnumType);\n          }\n          throw new IllegalArgumentException(\"Unknown spanner type \" + spannerType);\n        case POSTGRESQL:\n          Pattern pattern = Pattern.compile(\"([^\\\\[]+)\\\\[\\\\]\");\n          Matcher m = pattern.matcher(spannerType);","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerSchema.java#L205-L241","documentation":"SpannerSchema.parseSpannerType parses a Spanner column type string for the GOOGLE_SQL dialect; for ARRAY<...> types it applies a regex to extract the element type, and throws IllegalArgumentException(\"Invalid ARRAY type: ...\") when the regex fails to match. This usually means the type string is malformed or an array-of-array/proto form the parser doesn't support.","triggerScenarios":"Reading a Spanner schema (SpannerSchema.create / schema retrieval for SQL sources) where a column's declared type is an ARRAY whose text doesn't match the expected ARRAY<x> pattern — e.g., ARRAY<ARRAY<INT64>> nested arrays, malformed DDL, or types like ARRAY<PROTO<...>> the parser can't decompose.","commonSituations":"Schemas using nested arrays (Spanner supports ARRAY<STRUCT<...>> but nesting is limited); newer Spanner types (e.g., VECTOR) appearing in ARRAY position not supported by the Beam version; hand-written/DDL-migrated type strings with unusual spacing.","solutions":["Inspect the offending column type from the message and check if it is a nested array; Beam's Spanner schema mapper only handles one level — flatten the schema via a view/TVF.","Upgrade Beam to the latest version, which supports more Spanner types.","Exclude the unsupported column from the columns list when configuring the Spanner read.","If the type string looks genuinely malformed, fix the table DDL in Spanner."],"exampleFix":"// before: schema has ARRAY<ARRAY<INT64>> column\nSpannerSchema.create(spannerSchema, Dialect.GOOGLESQL); // throws\n// after: project out the nested column\nSpannerRead.of(config).withColumns(\"id\", \"name\"); // exclude nested-array column","handlingStrategy":"validation","validationCode":"// Skip array columns the mapper can't handle\nList<String> safeColumns = columns.stream()\n    .filter(c -> !c.type.toUpperCase().startsWith(\"ARRAY<ARRAY\"))\n    .map(c -> c.name).collect(toList());","typeGuard":null,"tryCatchPattern":"try { schema = SpannerSchema.create(spannerSchema, dialect); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Invalid ARRAY type\")) { /* drop or flatten that column */ } throw e; }","preventionTips":["Avoid nested ARRAY<ARRAY<...>> columns in tables read by Beam.","Upgrade Beam before adopting brand-new Spanner types.","Project only needed columns with withColumns(...)."],"tags":["java","beam","spanner","schema","type-parsing"],"backgroundTag":"unsupported-dtype","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"}