apache/beam · error · IllegalArgumentException
Failed to print type: {row}
Error message
Failed to print type: {row} What it means
columnTypeJsonFrom converts a JSON row describing a Spanner column type into a ColumnType proto, using a proto printer on extracted fields. If printer.apt/ printing throws InvalidProtocolBufferException, the row's JSON values are malformed for the expected proto-JSON schema and the mapper throws 'Failed to print type'. This signals that the row does not match the expected change stream column-type structure.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/changestreams/mapper/ChangeStreamRecordMapper.java:699
try {
final String type =
this.printer.print(
Optional.ofNullable(valueMap.get(TYPE_COLUMN))
.orElseThrow(IllegalArgumentException::new));
return new ColumnType(
Optional.ofNullable(valueMap.get(NAME_COLUMN))
.orElseThrow(IllegalArgumentException::new)
.getStringValue(),
new TypeCode(type),
Optional.ofNullable(valueMap.get(IS_PRIMARY_KEY_COLUMN))
.orElseThrow(IllegalArgumentException::new)
.getBoolValue(),
(long)
Optional.ofNullable(valueMap.get(ORDINAL_POSITION_COLUMN))
.orElseThrow(IllegalArgumentException::new)
.getNumberValue());
} catch (InvalidProtocolBufferException exc) {
throw new IllegalArgumentException("Failed to print type: " + row);
}
}
private Mod modFrom(Struct struct) {
final String keys = struct.getJson(KEYS_COLUMN);
final String oldValues =
struct.isNull(OLD_VALUES_COLUMN) ? null : struct.getJson(OLD_VALUES_COLUMN);
final String newValues =
struct.isNull(NEW_VALUES_COLUMN) ? null : struct.getJson(NEW_VALUES_COLUMN);
return new Mod(keys, oldValues, newValues);
}
private Mod modJsonFrom(Value row) {
try {
Map<String, Value> valueMap = row.getStructValue().getFieldsMap();
final String keys =
this.printer.print(
Optional.ofNullable(valueMap.get(KEYS_COLUMN))View on GitHub (pinned to 12126d8942)
Solutions
- Verify the row contains the expected columns (TYPE, ORDINAL_POSITION, etc.) as valid proto-JSON.
- Check that values were parsed with this.parser before being passed to the printer — do not pass raw strings.
- Align SDK version: regenerate/refresh rows with the same Beam version that will read them.
- Wrap the mapping call in try-catch to surface the offending row without killing the pipeline.
- Inspect the row content in the exception message for missing/invalid fields.
Example fix
// before
ColumnType type = mapper.columnTypeJsonFrom(row); // throws on malformed row
// after
try {
ColumnType type = mapper.columnTypeJsonFrom(row);
} catch (IllegalArgumentException e) {
LOG.error("Skipping malformed column-type row: %s", e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean hasRequiredColumnTypeFields(java.util.Map<String, com.google.protobuf.Value> map) {
return map != null && map.containsKey("TYPE") && map.containsKey("ORDINAL_POSITION");
} Type guard
boolean isNonNullJsonTypeValue(com.google.protobuf.Value v) {
return v != null && v.getKindCase() == com.google.protobuf.Value.KindCase.STRING_VALUE;
} Try / catch
try {
ColumnType t = columnTypeJsonFrom(row);
} catch (IllegalArgumentException e) {
LOG.error("Cannot map column type row: %s", e.getMessage());
} Prevention
- Parse rows with the same JsonFormat parser used by the mapper before mapping.
- Keep test fixtures generated from real Spanner responses, not hand-written JSON.
- Check for required keys (TYPE, ORDINAL_POSITION) before conversion.
- Pin connector/SDK versions in CI to avoid format drift.
When it happens
Trigger: Calling columnTypeJsonFrom with a row whose TYPE/ORDINAL_POSITION etc. fields are not valid proto-JSON Value messages, so the protobuf printer throws while serializing; also triggered when required keys resolve to Value objects incompatible with the printer.
Common situations: Malformed or hand-crafted test fixtures; rows produced by a different Spanner schema/connector version; corrupted metadata rows; passing wrong Value maps (e.g. missing or wrongly-typed fields) into the mapper.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to print mod: {row}
- Failed to parse record into proto: {row}
- Could not encode message as bytes
- Failed to convert PipelineOptions to JSON
- Failed to parse DataStore key from bytes.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a2ec5f20280ba48b.
Report an issue: GitHub.