apache/beam · error · java.lang.UnsupportedOperationException

Unexpected Protocol Buffers field type

Error message

Unexpected Protocol Buffers field type: ${type}

What it means

recursivelyAddDescriptors walks a proto message's fields to collect all descriptors (and registry entries) needed for dynamic message construction. It handles scalars, enums, and nested MESSAGE types; any other field Type reaching the default branch throws UnsupportedOperationException, since the collector doesn't know how to descend into that field kind.

Solutions

  1. Rewrite the proto2 `group` declaration as an ordinary nested message field.
  2. Check which field type triggers it (from the exception's type text) and replace it with a supported scalar/message/enum type.
  3. Upgrade Beam to a version whose recursivelyAddDescriptors covers the field type, or pre-transform the FileDescriptorSet before registering it.

Example fix

// before (proto2)
message SearchResponse {
  repeated group Result = 1 { required string url = 2; } // GROUP -> UnsupportedOperationException
}
// after
message SearchResponse {
  message Result { required string url = 2; }
  repeated Result result = 1;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: walk descriptors first and fail fast on unhandled kinds such as GROUP
static boolean hasUnsupportedKind(Descriptors.Descriptor d, Set<String> visited) {
  if (!visited.add(d.getFullName())) return false;
  for (Descriptors.FieldDescriptor f : d.getFields()) {
    if (f.getType() == Descriptors.FieldDescriptor.Type.GROUP) return true;
    if (f.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && hasUnsupportedKind(f.getMessageType(), visited)) return true;
  }
  return false;
}

Try / catch

try { registry = ProtobufUtil.registerProtoDescriptors(...); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unexpected Protocol Buffers field type:")) { /* rewrite that field kind in the proto */ } else throw e; }

Prevention

When it happens

Trigger: Building a dynamic proto message/coder for a message type that contains a field kind outside the handled set — most commonly a GROUP field or an unexpected type produced by parsing a FileDescriptorSet with kinds the routine doesn't model.

Common situations: Old proto2 definitions using `group` syntax; programmatically constructed descriptors with unusual types; Beam expansion responses carrying descriptors the local collector can't walk.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/5733b043546d25db. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtobufUtil.java:148

      case INT64:
      case SFIXED32:
      case SFIXED64:
      case SINT32:
      case SINT64:
      case STRING:
      case UINT32:
      case UINT64:
        // Primitive types do not transitively access anything else.
        break;

      case GROUP:
      case MESSAGE:
        // Recursively adds all the fields from this nested Message.
        recursivelyAddDescriptors(field.getMessageType(), descriptors, registry);
        break;

      default:
        throw new UnsupportedOperationException(
            "Unexpected Protocol Buffers field type: " + field.getType());
    }
  }
}

View on GitHub (pinned to 12126d8942)