# proto: 消息字段 "User.name" 是必填的但未设置

- **ID:** `go/protobuf-message-field-not-set`
- **领域:** go
- **类别:** data_error
- **验证级别:** ai_generated
- **修复率:** 80%

## 根因

proto2 的 required 字段（或 proto3 中期望字段存在的场景）在序列化前未填充。proto3 移除了 required，因此通常来自 proto2 文件或 protoc-gen-validate 等校验库。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| google.golang.org/protobuf v1.28+ | active | — | — |

## 解决方案

1. **** (95% 成功率)
   ```
   u := &pb.User{Name: "alice", Email: "a@example.com"}
if err := proto.CheckInitialized(u); err != nil {
    return fmt.Errorf("invalid user: %w", err)
}
b, err := proto.Marshal(u)
   ```
2. **** (90% 成功率)
   ```
   // user.proto: string name = 1 [(validate.rules).string = {min_len: 1}];
if err := u.Validate(); err != nil {
    return status.Errorf(codes.InvalidArgument, "%v", err)
}
   ```

## 无效尝试

- **** — AllowPartial only suppresses the marshal error; it still emits a message missing the required field, which the peer will reject on unmarshal. (85% 失败率)
- **** — Removing required breaks backward compatibility and shifts the failure to runtime nil dereferences downstream. (60% 失败率)
