# proto: Marshal 被调用时传入了 nil 消息

- **ID:** `go/protobuf-proto-marshal-nil-message`
- **领域:** go
- **类别:** runtime_error
- **验证级别:** ai_generated
- **修复率:** 80%

## 根因

向 proto.Marshal 或 protojson.Marshal 传入了 nil 的 protobuf 消息指针，通常源自处理器在错误路径返回 nil 指针而未做检查。

## 版本兼容性

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

## 解决方案

1. **** (95% 成功率)
   ```
   if msg == nil {
    return nil, status.Error(codes.Internal, "nil message")
}
b, err := proto.Marshal(msg)
if err != nil { return nil, status.Error(codes.Internal, err.Error()) }
   ```
2. **** (90% 成功率)
   ```
   func (s *srv) Get(ctx context.Context, req *pb.GetReq) (*pb.GetResp, error) {
    if req == nil { return &pb.GetResp{}, nil }
    return &pb.GetResp{Id: req.Id}, nil
}
   ```

## 无效尝试

- **** — Swallowing the panic leaves the caller with no message and no error, causing silent data loss downstream. (85% 失败率)
- **** — Changes wire semantics; clients expecting a specific message type get an unrelated type and may fail to unmarshal. (70% 失败率)
