fix(openapi): declare method_not_allowed and unknown-code tolerance

Why

v1.yaml's Error.code enum omitted method_not_allowed, which the server emits: the transport middleware rewrites stdlib 405s into the error envelope on every declared path. The two contract documents also disagreed on how clients should treat unknown codes. This adopts gitlab-v1.yaml's enum-plus-tolerate-unknown framing in v1.yaml and adds a managementapi enum-to-transport-constants coupling test mirroring the existing gitlabapi one, since the missing tripwire is how the gap survived.

Review surfaced a second inaccuracy in the same block. The description claimed the envelope covers every error path, but /api/v1/<slug>/... is a non-OCI row in the auth dispatch table, so a 401 there commits the status with an empty body and a WWW-Authenticate challenge. Eighteen operations declared a JSON body the surface never sends.

What

  • not_implemented stays out deliberately. Staged 501s carry no contract weight, per the option (b) decision recorded on docs(openapi): add S17 Phase 3 artifact read co... (!1129 - merged) • Hayley Swimelar • 19.3.
  • gitlab-v1.yaml needs no enum change: its surface 404s wrong methods.
  • The tolerance sentence is hoisted into info.description verbatim from gitlab-v1.yaml, so the response-enum entry in api-style.md is backed document-wide rather than by one field's prose. Error opens to match every other response schema in the document. transport.Envelope is what keeps the emitted key set closed.
  • unauthorized leaves the coupling test's emittable list but stays in the enum. No envelope carrying it is serialized on this surface, and removing an enum value would be breaking.

E2E scenarios

No scenario is added or affected. The catalogs are OCI and docker only (docs/testing/e2e/docker.md and oci.md), and no runtime behavior changed: the server already emitted method_not_allowed, and already answered 401 with an empty body and a challenge. Only the declarations moved.

Test plan

go test ./internal/managementapi/ ./internal/gitlabapi/ and redocly lint --config api/openapi/redocly.yaml pass. Each contract tripwire was verified red by mutation: removing the enum entry fails both the coupling test and the new 405 test, and removing the info.description sentence fails the coupling test.

Spec coverage

AC Criterion Where
1 Enum lists the 9 documented codes in transport-constant order 5e3407ee (Subset bounds both ways, exact membership checked manually)
2 Tolerance sentence in the code description, test asserts the phrase 5e3407ee
3 405 behavior documented in the Error schema description, no per-operation 405 5e3407ee, prose pinned by 685fbd10
4 No hunk in gitlab-v1.yaml branch diff, verified
5 Coupling test fails when method_not_allowed is removed 5e3407ee, verified red
6 api-style.md classifies response-enum additions as non-breaking f8e20c66, backed document-wide by 0de6ffae
7 Diff touches only v1.yaml, contract_test.go, api-style.md branch diff, verified
8 401 declares no body and a WWW-Authenticate header 0de6ffae
9 A real 405 validates against the contract's Error schema 0de6ffae, verified red

Related to Declare every reachable error code in both API ... (#412 - closed) • Hayley Swimelar

Context for LLM agents

The wholesale v1.yaml rewrite an earlier revision of this description warned about has landed on main. The branch is rebased onto it and git re-applied the Error-block hunks cleanly, verified against the merged document. The tripwires are TestContract_ErrorCodeEnum_MatchesTransportCodes, TestContract_MethodNotAllowed_MatchesErrorSchema, and the Contains assertions on the tolerance sentence, the 405 prose, Allow, and WWW-Authenticate. Dropping any of those hunks fails the managementapi suite.

Non-goals:

  • Declaring X-Request-ID is Declare X-Request-ID on both API contracts (#413 - closed) • Hayley Swimelar, not this MR.
  • not_implemented and service_unavailable are omitted deliberately. Neither is a documented part of the v1 error surface: staged 501s carry no contract weight, and load-shedding 503s are infrastructure behavior.
  • Opening Error does not invite new envelope fields. transport.Envelope remains the fixed struct that decides the emitted key set. The schema stops duplicating that guarantee in a document whose every other response schema is open.
Edited by Hayley Swimelar

Merge request reports

Loading
Loading