apache/beam · error · java.lang.RuntimeException

Failed to get oneof from proto. oneof

Error message

Failed to get oneof from proto. oneof: %s, subfield: %s

What it means

FromProtoOneOfGetter.getFromProto reads the currently-set member of a proto oneof and converts it to a Beam OneOfType value. If finding the subfield descriptor, hasField/getField, or the value conversion throws, it is wrapped in a RuntimeException naming the oneof field and subfield, keeping the root cause attached.

Solutions

  1. Check the wrapped cause to identify the failing subfield
  2. Ensure oneof subfield names in the proto match those used to build the Beam schema
  3. Regenerate/rebuild schema artifacts after proto changes
  4. Validate the message instance uses the same descriptor as the converter (same FileDescriptor set)

Example fix

// before
// oneof { string a = 1; } renamed to b in proto, schema stale -> throws
// after
// update schema: oneof { string b = 1; } and regenerate the Beam schema/converter
Defensive patterns

Strategy: try-catch

Validate before calling

// verify each oneof subfield resolves on the descriptor
for (String sub : oneOfFieldNames) { if (descriptor.findFieldByName(sub) == null) throw new IllegalStateException("missing oneof subfield " + sub); }

Try / catch

try { value = oneOfGetter.getFromProto(message); } catch (RuntimeException e) { LOG.error("oneof {} failed: {}", e.getMessage(), e.getCause()); throw e; }

Prevention

When it happens

Trigger: Converting a proto message to a Beam Row where a oneof member's descriptor lookup fails (subfield name not found), or reading/converting the oneof member value throws a RuntimeException.

Common situations: Proto schema changed so a oneof subfield name no longer matches the Beam schema; descriptor mismatch between message instance and converter; a member converter throwing on unexpected values.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoBeamConverter.java:451

        converters.put(field.getName(), createProtoToBeamConverter(field.getType()));
      }
      return converters;
    }

    @Override
    public OneOfType.@Nullable Value getFromProto(Message message) {
      Descriptors.Descriptor descriptor = message.getDescriptorForType();
      for (Map.Entry<String, ProtoToBeamConverter<Object, Object>> entry : converter.entrySet()) {
        String subFieldName = entry.getKey();
        try {
          ProtoToBeamConverter<Object, Object> value = entry.getValue();
          Descriptors.FieldDescriptor fieldDescriptor = descriptor.findFieldByName(subFieldName);
          if (message.hasField(fieldDescriptor)) {
            Object protoValue = message.getField(fieldDescriptor);
            return oneOfType.createValue(subFieldName, value.convert(protoValue));
          }
        } catch (RuntimeException e) {
          throw new RuntimeException(
              String.format(
                  "Failed to get oneof from proto. oneof: %s, subfield: %s",
                  field.getName(), subFieldName),
              e);
        }
      }
      return null;
    }
  }

  static class ToProto implements SerializableFunction<Row, Message> {
    private transient Descriptors.Descriptor descriptor;
    private transient Map<String, ToProtoSetter<Object>> toProtos;

    public ToProto(Descriptors.Descriptor descriptor) {
      initialize(descriptor);
    }

View on GitHub (pinned to 12126d8942)