go data_error ai_generated true

proto: field "pb.Config.Timeout" is already set in oneof "pb.Config.value"

ID: go/proto-oneof-set-twice

Also available as: JSON · Markdown · 中文
80%Fix Rate
84%Confidence
0Evidence
2024-09-11First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
google.golang.org/protobuf 1.28+ active

Root Cause

A oneof field was assigned twice on the same message. In google.golang.org/protobuf, setting a oneof field clears the others but setting the same field via reflection twice can trigger this in some generated code paths.

generic

中文

同一消息上的 oneof 字段被赋值两次。在 google.golang.org/protobuf 中,设置 oneof 字段会清除其他字段,但通过反射对同一字段设置两次可能在某些生成代码路径中触发此错误。

Workarounds

  1. 95% success
    Use the generated oneof wrapper types explicitly:
    cfg := &pb.Config{}
    cfg.Value = &pb.Config_Timeout{Timeout: 5 * time.Second}
  2. 85% success
    Check which variant is set before assigning:
    if _, ok := cfg.Value.(*pb.Config_Timeout); !ok {
        cfg.Value = &pb.Config_Timeout{Timeout: d}
    }

Dead Ends

Common approaches that don't work:

  1. 70% fail

    proto.Reset clears all fields, losing unrelated data you already populated.

  2. 80% fail

    The panic leaves the message in an inconsistent state; subsequent marshaling may produce corrupt output.