{"record":{"id":"cad04725ddff4aa7","repo":"apache/beam","slug":"failed-to-print-type-modstructvalue","errorCode":null,"errorMessage":"Failed to print type: {modStructValue}","messagePattern":"Failed to print type: (.+?)","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/changestreams/mapper/ChangeStreamRecordMapper.java","lineNumber":393,"sourceCode":"  String convertModValueProtosToJson(\n      List<com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.ModValue> modValueProtos,\n      List<com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.ColumnMetadata>\n          columnMetadataProtos) {\n    com.google.protobuf.Struct.Builder modStructValueBuilder =\n        com.google.protobuf.Struct.newBuilder();\n    for (com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.ModValue modValueProto :\n        modValueProtos) {\n      final String columnName =\n          columnMetadataProtos.get(modValueProto.getColumnMetadataIndex()).getName();\n      final Value columnValue = modValueProto.getValue();\n      modStructValueBuilder.putFields(columnName, columnValue);\n    }\n    Value modStructValue = Value.newBuilder().setStructValue(modStructValueBuilder.build()).build();\n    String modValueJson;\n    try {\n      modValueJson = this.printer.print(modStructValue);\n    } catch (InvalidProtocolBufferException exc) {\n      throw new IllegalArgumentException(\"Failed to print type: \" + modStructValue);\n    }\n    return modValueJson;\n  }\n\n  List<Mod> parseProtoMod(\n      List<com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.Mod> modProtos,\n      List<com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.ColumnMetadata>\n          columnMetadataProtos) {\n    List<Mod> mods = new ArrayList<>();\n    for (com.google.spanner.v1.ChangeStreamRecord.DataChangeRecord.Mod modProto : modProtos) {\n      final String keysJson =\n          convertModValueProtosToJson(modProto.getKeysList(), columnMetadataProtos);\n      final String oldValuesJson =\n          convertModValueProtosToJson(modProto.getOldValuesList(), columnMetadataProtos);\n      final String newValuesJson =\n          convertModValueProtosToJson(modProto.getNewValuesList(), columnMetadataProtos);\n      Mod mod = new Mod(keysJson, oldValuesJson, newValuesJson);\n      mods.add(mod);","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/changestreams/mapper/ChangeStreamRecordMapper.java#L375-L411","documentation":"convertModValueProtosToJson builds a struct Value from the modification's fields and prints it to JSON with a JsonFormat printer so TypeCode parsing works. If printing the mod struct Value fails (InvalidProtocolBufferException), IllegalArgumentException \"Failed to print type: <modStructValue>\" is thrown.","triggerScenarios":"A Mod's new/old values struct contains Value protos the printer cannot render — unsupported/unknown kind, malformed nested values from a newer Spanner proto, or corrupted mod data in the change stream record.","commonSituations":"Change stream records containing exotic value kinds (uninterpreted bytes, new types) on an older connector; corrupted rows in the change stream; proto version drift between Spanner server output and client libraries.","solutions":["Upgrade Beam's Google Cloud Platform connector and google.protobuf/spanner libraries to the latest versions.","Inspect the printed modStructValue in the message to find the offending Value kind and check the source column's data.","Reset/re-read the change stream partition from a good timestamp if the record is corrupt.","Sanitize or convert exotic column types (e.g. commit-time/protobuf columns) to standard supported types in the tracked table."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"try { printer.print(modStructValue); } catch (InvalidProtocolBufferException e) { /* mod value not renderable */ }","typeGuard":null,"tryCatchPattern":"try { modValueJson = printer.print(modStructValue); } catch (InvalidProtocolBufferException e) {\n  log.error(\"Unprintable mod value: {}\", modStructValue, e);\n}","preventionTips":["Upgrade client protos when Spanner adds new Value kinds.","Avoid exotic column types (protobuf columns) in change-streamed tables.","Monitor for corrupt records and checkpoint/reset partitions from a clean timestamp."],"tags":["spanner","protobuf","json","java"],"backgroundTag":"json-marshal-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}