Skip to content

Seven routes declare a 422 the application already declares for every route #657

Description

@JArmandoAnaya

documented() in src/visionset/server/errors.py builds the responses= mapping a route spreads
into its decorator, and its own docstring says which statuses do not belong in a call to it: "401
arrives from protected_router() and 422/500/503 from the app, so neither belongs in a call to
this." UNIVERSAL_ERROR_RESPONSES is what makes that true — create_app applies 422, 500 and 503
at application level, to every route at once.

Seven of the seventy-eight call sites pass 422 anyway:

  • src/visionset/server/routes/batches.py:80documented(404, 422)
  • src/visionset/server/routes/batches.py:226documented(404, 409, 422)
  • src/visionset/server/routes/schemas.py:292documented(404, 409, 422)
  • src/visionset/server/routes/inference.py:95documented(409, 422)
  • src/visionset/server/routes/inference.py:130documented(404, 409, 422)
  • src/visionset/server/routes/inference.py:312documented(422)
  • src/visionset/server/routes/inference.py:339documented(404, 409, 422)

The published contract is unaffected. The entry documented(422) produces is the same
ERROR_RESPONSES[422] the application-level mapping supplies, so openapi.json is byte-identical
either way and no client sees a difference. What is affected is the convention: the rule and the
code disagree, and somebody deciding what to write on a new route finds seventy-one examples of one
answer and seven of the other, with the docstring siding with the majority.

There are two ways to settle it. Drop the redundant argument at the seven sites, or amend
documented()'s docstring if the redundancy is deliberate and worth keeping. The first looks
right, because the application-level declaration is described as load-bearing rather than
convenient — it is what overrides FastAPI's generated HTTPValidationError response and keeps that
model, and the second error shape it would imply, out of the contract entirely. A per-route repeat
of it adds nothing and invites the reading that the app-level entry is optional.

Found while correcting a published status claim on one of those seven routes (#655). Those call
sites are untouched by that work, which changed a docstring and the two generated artifacts and
nothing else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apivisionset.server — REST API and OpenAPI contractbackendvisionset Python distribution — kernel, server, cli, mcp, formats

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions