CONCEPT Cited by 1 source
Breaking change requires major bump¶
Definition¶
A breaking change to a component (or API, or message schema) requires a major version bump. Once the major version has bumped, both the old and the new major version must be supportable side-by-side for as long as any client still pins the old major version. The rule is a discipline that, when combined with a migrate function at the major-version boundary, enables heterogeneous-client fleets (old apps + new apps) to coexist indefinitely without forced upgrade.
Canonical wiki instance (Yelp Konbini)¶
Konbini's worked example: Yelp wants
to change Button's text parameter from String to a custom
FormattedText supporting http links. Verbatim: "This is a
breaking change because older clients will receive a
different type of object for the text field, which they
don't know how to interpret." The JSON definition's
version field bumps from 0.8 to 1.0:
{
"name": "cookbook.Button",
"version": "1.0", // was "0.8"
"parameters": {
"text": { "type": "FormattedText",
"description": "A formatted text ..." },
...
}
}
Konbini auto-generates CookbookButtonV1 alongside the still-
existing CookbookButtonV0; it also generates an empty
migrate()
method that developers must implement to backport V1 to V0
for clients whose
spec version still references
CookbookButton: "0.8".
What counts as breaking¶
- Type change on an existing parameter —
String→FormattedText. - Removal of a parameter — older clients expecting the field will see it absent.
- Rename of a parameter — JSON key change breaks deserialisers.
- Narrowing of a union / enum — removing allowed values.
- Change in required-ness — making an optional field required.
- Semantic change — same shape, different meaning (subtle and hard to catch — not always a type signal, but still breaking).
What does not count as breaking (no major bump needed)¶
- Adding an optional parameter. Old clients ignore it. Minor bump only.
- Adding an enum value — if older clients have explicit
unknownhandling. If not, this is secretly breaking. - Documentation changes.
Preconditions for the discipline to hold¶
- Version is part of the wire format. Every request / every serialised component carries its version so both sides can reason about compatibility.
- Backward-compat story at every major boundary. Either a migrate function from N+1 → N, or an explicit decision not to support clients that pin N (failing closed).
- Old majors don't disappear silently. Removing
V0from the code base while clients still pin it breaks those clients — old majors need to live until the last client has upgraded past them.
Contrasts¶
- Protocol Buffers field compatibility — forbids rename-or-retype of existing fields by convention, using "add new fields, keep field tags stable, reserve removed tags". No version number in the wire; everything is additive.
- GraphQL schema evolution — deprecation directives on fields, with GraphQL servers handling the "field requested but deprecated" case. Looser than semver major bumps; enforcement depends on schema-lint tooling.
- REST API versioning (
/v1/vs/v2/) — per-endpoint, coarser than Konbini's per-component.
Seen in¶
- sources/2026-04-22-yelp-how-yelp-keeps-server-driven-ui-consistent-across-four-platforms — canonical wiki first source. Yelp Konbini enforces major-bump-on-breaking-change at the component-interface level; pairs with migrate functions and spec versions for the complete backward-compat story.