Skip to content
Latchkey

buf breaking: Detect Breaking Proto Changes in CI

buf breaking diffs the current proto module against a baseline (--against) and exits non-zero when a change breaks wire or source compatibility.

Schema changes that look harmless can break deployed clients. buf breaking compares against a git ref or image and names the exact field or message that broke.

What it does

buf breaking compiles both the current input and the --against baseline, then checks each enabled breaking rule (categories FILE, PACKAGE, WIRE, WIRE_JSON). FILE is the strictest (source compatibility); WIRE only flags on-the-wire breakage. It reports each incompatibility with the file and field involved.

Common usage

Terminal
# compare working tree against main on origin
buf breaking --against '.git#branch=main'

# compare against the previous commit
buf breaking --against '.git#ref=HEAD~1'

# compare against a prebuilt image
buf breaking --against image.binpb

# buf.yaml
# breaking:
#   use:
#     - FILE

Flags and options

Flag / configWhat it does
--against <input>Baseline: git ref, image file, dir, or tarball (required)
--path <path>Restrict the comparison to specific files
--error-format <fmt>text, json, msvs, or github-actions
breaking.useRule categories: FILE, PACKAGE, WIRE, WIRE_JSON
breaking.exceptSpecific breaking rules to skip
--exclude-importsIgnore changes in imported files

In CI

On pull requests, run buf breaking --against ".git#branch=main". Fetch enough git history (fetch-depth: 0 in actions/checkout) or the baseline ref is unavailable. Pick FILE for libraries, WIRE for services where source-level churn is acceptable but the wire format must stay stable.

Common errors in CI

A real violation reads like "Field "1" on message "User" changed type from "string" to "int64"" or "Previously present field "2" ... was deleted". "Failure: ... .git#branch=main: ... could not resolve ref" means the baseline ref is not fetched; deepen the checkout. "Failure: <against>: no .proto files were targeted" means the baseline path or module root is wrong.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →