Skip to content

Add strict_response_content_type option to ResponseValidation middleware#478

Open
whoward wants to merge 1 commit into
interagent:masterfrom
whoward:wh/strict-content-types
Open

Add strict_response_content_type option to ResponseValidation middleware#478
whoward wants to merge 1 commit into
interagent:masterfrom
whoward:wh/strict-content-types

Conversation

@whoward

@whoward whoward commented Jul 21, 2026

Copy link
Copy Markdown

Committee silently skips response body schema validation when the response Content-Type doesn't match any key declared in the OpenAPI spec's content map for that operation. This means a server returning application/vnd.api+json against a spec that only declares application/json passes validation without error. The new opt-in flag strict_response_content_type: false (default false for backwards compatibility) raises Committee::InvalidResponse in this case. The guard is skipped for responses with no content map at all (e.g. bare 204s), which continue to pass silently.

The check is implemented as a pre-guard in OperationWrapper#validate_response_params before handing off to openapi_parser's validate_response_body, since openapi_parser has no hook to express this policy without modifying the gem or repurposing the existing strict: flag. Status code lookup replicates openapi_parser's wildcard matching (4XX, default) via a private find_response_object_for_status helper. Content-Type params (e.g. charset=utf-8) are stripped via Rack::MediaType.type before matching, consistent with how validate_post_request_params handles request body content types.

This work implements #477

Committee silently skips response body schema validation when the response Content-Type
doesn't match any key declared in the OpenAPI spec's content map for that operation. This
means a server returning application/vnd.api+json against a spec that only declares
application/json passes validation without error. The new opt-in flag
strict_response_content_type: false (default false for backwards compatibility) raises
Committee::InvalidResponse in this case. The guard is skipped for responses with no
content map at all (e.g. bare 204s), which continue to pass silently.

The check is implemented as a pre-guard in OperationWrapper#validate_response_params
before handing off to openapi_parser's validate_response_body, since openapi_parser has
no hook to express this policy without modifying the gem or repurposing the existing
strict: flag. Status code lookup replicates openapi_parser's wildcard matching (4XX,
default) via a private find_response_object_for_status helper. Content-Type params
(e.g. charset=utf-8) are stripped via Rack::MediaType.type before matching, consistent
with how validate_post_request_params handles request body content types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant