Agent Wranglers

API-87Required

Never reuse or change a protobuf field number

Never give a protobuf field number a new name, type or meaning. When you delete a field, list its number and name under reserved.

How to do it

Protobuf sends field numbers, not names. A client built on the old file reads the new field's bytes as the old field, and stores wrong data without an error. The protobuf guide says never to reuse a tag number and to reserve deleted ones. Changing a field's type breaks reading in the same way. Make the first value of each enum ..._UNSPECIFIED = 0, so a missing value never reads as a valid choice. Add new fields instead, as make only additive changes says.

Examples

Plain text example

message Invoice {
  reserved 4;
  reserved "total";
  string id = 1;
  int64 total_cents = 2;
  string currency = 3;
  InvoiceStatus status = 5;
}

enum InvoiceStatus {
  INVOICE_STATUS_UNSPECIFIED = 0;
  INVOICE_STATUS_DRAFT = 1;
  INVOICE_STATUS_SENT = 2;
}

YAML example

# buf.yaml: CI runs `buf lint` and `buf breaking --against '.git#branch=main'`
version: v2
lint:
  use: [STANDARD]
breaking:
  use: [FILE]

How to check

A breaking-change tool, such as buf breaking, runs in CI against the main branch. It fails on a removed field without reserved, a changed type or a reused number. Every enum's zero value ends in _UNSPECIFIED.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/api-design/graphql-and-grpc/protobuf-field-numbers">Agent Wranglers API design playbook</a>. In code you write, add a comment next to it with the same link.