---
title: "Let a schema registry refuse breaking · Agent Wranglers"
url: https://agentwranglers.se/playbook/events/contracts-and-schemas/schema-compatibility
id: EVT-4
level: Required
risk: outage
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1123
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Let a schema registry refuse breaking changes

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Contracts and schemas](https://agentwranglers.se/playbook/events/contracts-and-schemas.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: EVT-4
- Level: Required
- Chapter: [Contracts and schemas](https://agentwranglers.se/playbook/events/contracts-and-schemas.md)
- Rule: Register every event schema in a schema registry with a compatibility mode, and let it refuse a new version that breaks the readers. Upgrade readers or writers first, in the order that mode demands.
- Check: In CI, try to register a version of a test schema that deletes a required field. The registry or the check refuses it and the build fails. Every subject in the registry has a mode other than `NONE`.
- Risk: The app down or unusable
- How: A producer that removes a field or changes its type stops every consumer that reads it. Old messages still sit in the topic. A registry, such as Confluent Schema Registry or Apicurio Registry, checks each new version against the old ones. Pick a mode per subject. `BACKWARD`, the usual default, means new readers can read data written with the last schema, so upgrade consumers first. `FORWARD` means old readers can read new data, so upgrade producers first. `FULL` means both. Add `_TRANSITIVE` when consumers replay old messages, so the check covers every earlier version. Never set `NONE` on a topic other teams read. Without a registry, run the same check in CI against the schemas in the contract from [Describe every channel in an AsyncAPI document](https://agentwranglers.se/playbook/events/contracts-and-schemas/asyncapi-contracts.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Shell example

```bash
# Ask the registry whether a new version is compatible before deploying the producer
curl -s -X POST -H 'Content-Type: application/vnd.schemaregistry.v1+json' \
  --data "{\"schema\": $(jq -Rs . < order-shipped.avsc)}" \
  https://registry.example.com/compatibility/subjects/shop.orders.shipped-value/versions/latest \
  | jq -e '.is_compatible == true'
```

### Python example

```python
import json
import requests

def is_compatible(registry: str, subject: str, schema: dict) -> bool:
    answer = requests.post(
        f"{registry}/compatibility/subjects/{subject}/versions/latest",
        headers={"Content-Type": "application/vnd.schemaregistry.v1+json"},
        data=json.dumps({"schema": json.dumps(schema)}),
        timeout=10,
    )
    answer.raise_for_status()
    return answer.json()["is_compatible"]
```

### JavaScript example

```js
export async function isCompatible(registry, subject, schema) {
  const answer = await fetch(`${registry}/compatibility/subjects/${subject}/versions/latest`, {
    method: 'POST',
    headers: { 'content-type': 'application/vnd.schemaregistry.v1+json' },
    body: JSON.stringify({ schema: JSON.stringify(schema) }),
    signal: AbortSignal.timeout(10_000),
  });
  if (!answer.ok) throw new Error(`registry answered ${answer.status}`);
  return (await answer.json()).is_compatible;
}
```

## Sources

- [Confluent Schema Registry, schema evolution and compatibility](https://docs.confluent.io/platform/current/schema-registry/fundamentals/schema-evolution.html)

## Related rules

- EVT-1 [Describe every channel in an AsyncAPI document](https://agentwranglers.se/playbook/events/contracts-and-schemas/asyncapi-contracts.md) in Integration and events

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/events/contracts-and-schemas/schema-compatibility">Agent Wranglers integration and events playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Version event payloads](https://agentwranglers.se/playbook/events/contracts-and-schemas/event-versions.md)
- Next: [Treat each source schema as a contract](https://agentwranglers.se/playbook/events/contracts-and-schemas/source-schema-contracts.md)
- [Contracts and schemas](https://agentwranglers.se/playbook/events/contracts-and-schemas.md)
