Summary
Tracking issue for the upstream CATS defect root-caused in #637 and filed as
Endava/cats#206.
CATS validates a 2xx response against the operation's declared example, not its schema.
When an example is present, the response body's property names (recursively) must be a subset of
the example's. The schema is never consulted — replacing it with {"type":"object"} or even true
still fails. When no example is present the check never runs at all.
This produced 428 of the 542 true positives (79%) in the 20260730T220551Z baseline, all
reported as "Not matching response schema" — a misleading label, since the schema was never the
thing being checked.
Why this is still open after #654
#654 remediated the findings legitimately rather than by suppression: the 23 genuinely
incomplete response examples in api-schema/tmi-openapi.json were completed, so the findings clear
and real schema regressions still surface. No false-positive rule was added.
That leaves two things to come back to:
- One site is unsatisfiable from the spec side.
MinimalDiagramModel.metadata is
additionalProperties: {type: string} — a free-form map whose keys are unbounded, so no example
can enumerate them. Expected to be the residual ~4 findings on
GET /threat_models/{id}/diagrams/{id}/model. These cannot be fixed until upstream does.
- A standing maintenance burden. Every response example must now stay exhaustive relative to
its schema, or CATS re-reports the operation. Nothing enforces that today, so the next added
optional property silently reintroduces the finding.
Acceptance Criteria
Related upstream defects
Two further CATS defects were noted in the same upstream issue as possibly sharing a code path, and
should be tracked alongside it:
ExamplesFields posts a schema-level object example as the whole body where the request
schema is an array — produces 400 "value must be an array" on assets/bulk and
documents/bulk.
- Array query params are comma-joined regardless of
explode: true — sends
?severity=high%2Chigh instead of severity=high&severity=high.
References
Summary
Tracking issue for the upstream CATS defect root-caused in #637 and filed as
Endava/cats#206.
CATS validates a 2xx response against the operation's declared
example, not itsschema.When an example is present, the response body's property names (recursively) must be a subset of
the example's. The schema is never consulted — replacing it with
{"type":"object"}or eventruestill fails. When no example is present the check never runs at all.
This produced 428 of the 542 true positives (79%) in the
20260730T220551Zbaseline, allreported as "Not matching response schema" — a misleading label, since the schema was never the
thing being checked.
Why this is still open after #654
#654 remediated the findings legitimately rather than by suppression: the 23 genuinely
incomplete response examples in
api-schema/tmi-openapi.jsonwere completed, so the findings clearand real schema regressions still surface. No false-positive rule was added.
That leaves two things to come back to:
MinimalDiagramModel.metadataisadditionalProperties: {type: string}— a free-form map whose keys are unbounded, so no examplecan enumerate them. Expected to be the residual ~4 findings on
GET /threat_models/{id}/diagrams/{id}/model. These cannot be fixed until upstream does.its schema, or CATS re-reports the operation. Nothing enforces that today, so the next added
optional property silently reintroduces the finding.
Acceptance Criteria
schema, a 20-line Python stub; deleting the
examplealone flips fail → pass)independent of CATS, so the likely answer is yes — but the obligation to keep them exhaustive
goes away, and the
MinimalDiagramModel.metadataresidual should clearan unfixed CATS for long
Related upstream defects
Two further CATS defects were noted in the same upstream issue as possibly sharing a code path, and
should be tracked alongside it:
ExamplesFieldsposts a schema-level object example as the whole body where the requestschema is an array — produces 400 "value must be an array" on
assets/bulkanddocuments/bulk.explode: true— sends?severity=high%2Chighinstead ofseverity=high&severity=high.References
HANDOFF.md— full triage, including theNote-vs-TeamNotediscriminator this explains