OpenAPI errors

Fix \"example\" vs \"examples\" errors in OpenAPI

example and examples follow different rules depending on where they sit, and mixing them up produces specs that look right but render blank docs or pass validation while being structurally wrong. Three shapes exist: OpenAPI's Media Type Object example (one value) and examples (a map of named {value: ...} objects), and OpenAPI 3.1's Schema Object examples, a real JSON Schema 2020-12 keyword that must be an array. Confusing the map shape with the array shape is the most common failure, and a schema-only validator often misses it. Reproduced with real tools on 2026-09-21.

How do you reproduce the error?

Take a 3.0 media-type examples block where each entry is written as a bare value instead of being wrapped in { value: ... } — a natural mistake if you're used to plain JSON:

content:
  application/json:
    schema:
      type: object
      properties:
        id: { type: string }
        status: { type: string }
    examples:
      basic:
        id: "msg_123"       # WRONG — should be nested under `value:`
        status: "sent"

swagger-cli validate v4.0.4 reports a wall of AJV noise, because the Example Object and Reference Object are checked as oneOf branches:

Swagger schema validation failed.
  #/paths/~1messages~1{id}/get/responses/200/content/application~1json/examples/basic must NOT have additional properties
  #/paths/~1messages~1{id}/get/responses/200/content/application~1json/examples/basic must NOT have additional properties
  #/paths/~1messages~1{id}/get/responses/200/content/application~1json/examples/basic must have required property '$ref'
  #/paths/~1messages~1{id}/get/responses/200/content/application~1json/examples/basic must match exactly one schema in oneOf

redocly lint v2.53.3 names the actual problem:

[3] api.yaml:29:19 at #/paths/~1messages~1{id}/get/responses/200/content/application~1json/examples/basic/id

Property `id` is not expected here.

Error was generated by the struct rule.

Fix it by wrapping each named example in value:, and swagger-cli validate returns a clean is valid.

The second shape: 3.1 schema-level examples is an array, not a map

This is the confusion unique to 3.1. OpenAPI 3.1's Schema Object is real JSON Schema 2020-12, and JSON Schema's examples keyword is an array of raw values — not the named-map shape that Media Type and Parameter Objects use. Writing the map shape at the schema level (an easy mistake if you've internalized the Media Type pattern) produces this:

properties:
  status:
    type: string
    examples:               # WRONG at the schema level — this is the media-type shape
      basic:
        value: "sent"

We ran both tools against this. swagger-cli validate v4.0.4 (AJV against the OpenAPI meta-schema) reports:

example-31-schema-bad-examples.yaml is valid

redocly lint v2.53.3 catches it precisely:

[3] api.yaml:28:23 at #/paths/~1messages~1{id}/get/responses/200/content/application~1json/schema/properties/status/examples

Expected type `array` but got `object`.

Error was generated by the struct rule.

This is the same pattern as an unresolved $ref (see the unresolved reference post): the meta-schema check treats examples as loosely typed enough to pass, while a semantic linter checks the actual JSON Schema 2020-12 constraint. The correct form:

properties:
  status:
    type: string
    examples: ["sent", "failed"]   # JSON Schema 2020-12 array

Why does OpenAPI have three different shapes?

Per the OpenAPI 3.1.1 specification, the Media Type Object states: "The example and examples fields are mutually exclusive, and if either is present it SHALL override any example in the schema." That's OpenAPI's own Example Object system — example is one raw value, examples is a map of {summary?, description?, value | externalValue} objects, for rendering named request/response samples in docs and mock tools.

The Schema Object differs because OpenAPI 3.1 replaced its custom Schema Object with actual JSON Schema 2020-12 (see OpenAPI 3.1 vs 3.0 for the full change list). JSON Schema's examples keyword is simply an array of values that satisfy the schema — no names, no value wrapper. There is no map form at the schema level.

Schema-level singular example still exists in 3.1 for backward compatibility, but the preference moved to examples since example isn't a JSON Schema keyword at all — it's an OpenAPI-only carryover. We ran a spec using schema-level example: "sent" under 3.1 through both swagger-cli and redocly lint; neither flagged it. Nothing stops you from shipping it, which is exactly why it's worth knowing the preferred form rather than relying on tooling to catch it.

The three shapes side by side

Location Field Shape Since
Media Type Object / Parameter Object example one raw value 3.0 and 3.1 (unchanged)
Media Type Object / Parameter Object examples map of named {value: ...} objects 3.0 and 3.1 (unchanged)
Schema Object example one raw value 3.0; still valid but de-emphasized in 3.1
Schema Object examples array of raw values 3.1 only (JSON Schema 2020-12)

How do you fix it?

Match the shape to the location:

# Media type / parameter — named examples, wrapped in `value`
examples:
  basic:
    value:
      id: "msg_123"
      status: "sent"

# Schema Object (3.1) — bare array, no names, no wrapper
properties:
  status:
    type: string
    examples: ["sent", "failed"]

If you're maintaining both 3.0 and 3.1 copies of a spec, don't try to reuse the same examples block for both the schema and the media type — they mean different things even though the key is spelled the same.

How different tools react

Tool Bad media-type examples (missing value) Bad schema-level examples (map instead of array)
swagger-cli validate (AJV) Fails, but with a generic multi-branch oneOf error Passes silently — no error
redocly lint (semantic linter) Fails with exact property path (struct rule) Fails with Expected type \array` but got `object`.`
Docs renderers Example section renders blank or throws Example section renders blank or throws
SDK/codegen tools Usually ignored — examples rarely affect generated types Usually ignored — examples rarely affect generated types

Codegen tools generally don't fail on bad examples at all, because example values don't drive type generation — the risk sits entirely on the docs and mocking side, which is why a schema-shape validator missing the array/map mismatch matters: it's often the only check standing between a bad example and a broken docs page.

How to catch this before it ships

  1. Run a semantic linter — redocly lint, spectral lint, or the free in-browser OpenAPI validator — since swagger-cli/AJV misses the schema-level array-vs-map mistake entirely, as shown above.
  2. When upgrading 3.0 to 3.1, check examples: under properties: (schema level) separately from examples: under content.<media-type>: — a global find-and-replace breaks one of them.
  3. Prefer schema-level examples (array) over example (singular) in new 3.1 specs — it's the form aligned with plain JSON Schema tooling outside the OpenAPI ecosystem.

Sourced validates example shapes as part of every spec push, and renders hosted docs from the same spec you push — so a malformed examples block shows up as a docs preview gap before it reaches a customer. Create hosted docs from your repo or start a free report to see your own spec's examples rendered correctly.

FAQ

Is example deprecated in OpenAPI 3.1?

The Schema Object's singular example field still validates in 3.1 and no mainstream tool rejects it — confirmed directly with swagger-cli and redocly lint, neither of which flagged it. But 3.1's Schema Object is JSON Schema 2020-12, where examples (the array form) is the real keyword; example is an OpenAPI-only carryover. New 3.1 specs should prefer examples.

Do example and examples at the Media Type level change between OpenAPI 3.0 and 3.1?

No. The Media Type Object and Parameter Object fields are unchanged between versions — same mutual-exclusivity rule, same map-of-named-objects shape for examples. Only the Schema Object's examples changed, because that's the part of the spec that moved to JSON Schema 2020-12.

Why did swagger-cli pass a spec with the wrong examples shape at the schema level?

It validates against the OpenAPI meta-schema using AJV, and depending on how loosely that meta-schema types examples, an object can pass where an array was expected. Same class of gap as the unresolved $ref post: a structural JSON Schema check and a semantic linter don't catch the same things.

Will a bad examples block break my generated SDK?

Almost never. SDK and MCP codegen tools generate types and methods from schema, not from example/examples. The risk is a blank or broken example in your rendered docs, not a build failure.

What's the fastest way to check every example in a large spec?

Run redocly lint with the default ruleset — its struct rule checks every field's shape in one pass, including nested schema-level examples arrays, and reports the exact file, line, and property path rather than a generic AJV branch error.

Does this affect OpenAPI 3.0 specs at all?

Only the media-type examples-missing-value mistake — the schema-level array-vs-map confusion is 3.1-only, since 3.0's Schema Object never had a JSON-Schema-shaped examples keyword.