cd /news/developer-tools/my-openapi-differ-flagged-a-breaking… · home › topics › developer-tools › article
[ARTICLE · art-148001] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

My OpenAPI differ flagged a breaking change that broke nobody — the enum shrank on the response side

A developer built an OpenAPI changelog generator that diffs two specs and outputs structured breaking-change lists without LLM rewriting, and its first dogfood run flagged a single breaking change — a response-side enum shrinking from three values to two — that had already shipped without breaking anything. The incident led to a direction-aware differ that treats the same textual delta differently depending on whether the schema sits on the request or response side, plus spec normalization (expanding $refs, sorting keys, canonicalizing) to eliminate false diffs from property ordering. The tool is packaged as the OpenAPI Changelog Generator, taking a base spec URL and a new spec and returning a human-readable changelog alongside a machine-readable change list.

by read1 min views1 publishedOct 9, 2026

I built an OpenAPI changelog generator because writing API release notes was eating my afternoons: diff two specs, output a structured list of breaking changes, no LLM rewriting history. First real dogfood run — comparing my own API's v3 spec against v2 — it flagged exactly one breaking change. Except that change had shipped a week earlier and nothing broke.

The delta: a status field's enum went from ["queued","shipped","failed"] to ["queued","shipped"]. Textbook breaking change, the differ said. But that field lived in a response schema. A server returning fewer enum values cannot surprise a client that already handles all three — the client's switch statement still compiles. The server promised less variety, not less data.

That's when it clicked: breaking-ness has a direction, and the same textual delta flips meaning depending on which way the schema points.

number to integer — all breaking. Old clients start sending rejected payloads. The inverse bit me earlier too: adding a value to a response enum means old clients suddenly receive data their validators reject. Same operation, opposite verdict, depending on the boundary side.

Second fix, less glamorous: I now normalize specs before diffing — expand $ref s, sort keys, canonicalize. Without that, two semantically identical specs whose properties happened to be ordered differently produced a wall of fake diffs. JSON comparison is not semantic comparison.

The direction-aware version now gates my own spec releases before anything ships. I eventually packaged it as the OpenAPI Changelog Generator — it takes a base spec URL plus the new spec and returns a human-readable changelog alongside a machine-readable change list.

If you diff specs with a naive property-level tool, check which side of the boundary the changed schema sits on. It flips the verdict more often than you'd expect.

── more in #developer-tools 4 stories · sorted by recency
── more on @openapi changelog generator 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/my-openapi-differ-fl…] indexed:0 read:1min 2026-10-09 · —