{"record":{"id":"fd557d7714f4316c","repo":"apache/beam","slug":"error-processing-struct-to-row-e-getmessage","errorCode":null,"errorMessage":"Error processing struct to row: {e.getMessage()}","messagePattern":"Error processing struct to row: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/StructUtils.java","lineNumber":81,"sourceCode":"        schema.getFields().stream()\n            .collect(\n                HashMap::new,\n                (map, field) -> map.put(field.getName(), getStructValue(struct, field)),\n                Map::putAll);\n    return Row.withSchema(schema).withFieldValues(structValues).build();\n  }\n\n  public static Schema structTypeToBeamRowSchema(StructType structType, boolean isRead) {\n    Schema.Builder beamSchema = Schema.builder();\n    structType\n        .getFieldsList()\n        .forEach(\n            field -> {\n              Schema.FieldType fieldType;\n              try {\n                fieldType = convertSpannerTypeToBeamFieldType(field.getType());\n              } catch (IllegalArgumentException e) {\n                throw new IllegalArgumentException(\n                    \"Error processing struct to row: \" + e.getMessage());\n              }\n              // Treat reads from Spanner as Nullable and leave Null handling to Spanner\n              if (isRead) {\n                beamSchema.addNullableField(field.getName(), fieldType);\n              } else {\n                beamSchema.addField(field.getName(), fieldType);\n              }\n            });\n    return beamSchema.build();\n  }\n\n  public static Schema.FieldType convertSpannerTypeToBeamFieldType(\n      com.google.spanner.v1.Type spannerType) {\n    switch (spannerType.getCode()) {\n      case BOOL:\n        return Schema.FieldType.BOOLEAN;\n      case BYTES:","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/StructUtils.java#L63-L99","documentation":"structTypeToBeamRowSchema wraps an IllegalArgumentException raised while converting a Spanner struct field's type into a Beam Schema.FieldType, rethrowing it with the prefix \"Error processing struct to row: \". It indicates at least one column of the Spanner STRUCT/row has a type the converter does not support; the original message is appended.","triggerScenarios":"Calling StructUtils.structTypeToBeamRowSchema (directly or via SpannerIO reads of STRUCT columns) on a Spanner type whose code hits an unsupported branch in convertSpannerTypeToBeamFieldType, e.g. a STRUCT-typed or otherwise unrecognized field type.","commonSituations":"Reading Spanner tables containing STRUCT columns or newer Spanner types (e.g. proto/json columns on newer SDK/backends) with an older Beam SDK that lacks the mapping.","solutions":["Read the wrapped message to identify the offending field type and remove/flatten unsupported columns in the query (e.g. avoid selecting STRUCT columns).","Upgrade the Beam Google Cloud Platform SDK to a version that maps the offending Spanner type.","Cast unsupported columns to supported types (STRING, NUMERIC, etc.) in the SQL query before reading."],"exampleFix":"// before\nSELECT id, nested_struct FROM my_table\n// after\nSELECT id, TO_JSON_STRING(nested_struct) AS nested_struct_json FROM my_table","handlingStrategy":"try-catch","validationCode":"// pre-check schema fields against known-supported Spanner codes\nSet<String> supported = Set.of(\"BOOL\",\"INT64\",\"FLOAT64\",\"NUMERIC\",\"STRING\",\"DATE\",\"TIMESTAMP\",\"BYTES\",\"ARRAY\");\nboolean allSupported = type.getStructFields().stream()\n    .allMatch(f -> supported.contains(f.getType().getCode().name()));","typeGuard":null,"tryCatchPattern":"try {\n  Schema schema = StructUtils.structTypeToBeamRowSchema(spannerType, isRead);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Unsupported Spanner schema: {}\", e.getMessage());\n  throw new PipelineException(\"Failing read; see cause for the unsupported column type\", e);\n}","preventionTips":["Avoid STRUCT columns in Spanner read queries.","Pin and test the Beam SDK version against your database's schema.","Cast exotic columns to supported types in SQL."],"tags":["spanner","schema","type-conversion","java"],"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"}