Summary
When validate_responses=True is enabled, Connexion validates that required response headers are present, but does not validate that header values conform to their defined schema. This allows handlers to return headers with invalid values (wrong type, out of range, invalid enum) without triggering a validation error.
Current Behavior
A handler can return:
def get_items():
return {"items": []}, 200, {"X-Total-Count": "not-a-number"}
Even when the spec defines X-Total-Count as an integer, Connexion accepts this and returns the response to the client.
Expected Behavior
When validate_responses=True, Connexion should validate response header values against their schema and raise NonConformingResponseHeaders if validation fails, returning a 500 error (similar to how missing required headers are handled).
Reproduction
OpenAPI 3.0 spec:
openapi: "3.0.0"
info:
title: Test API
version: "1.0"
paths:
/items:
get:
operationId: api.get_items
responses:
"200":
description: Success
headers:
X-Total-Count:
required: true
schema:
type: integer
minimum: 0
content:
application/json:
schema:
type: object
Handler:
def get_items():
return {"items": []}, 200, {"X-Total-Count": "invalid"}
Result: Returns 200 with invalid header
Expected: Returns 500 with validation error
Requirements
Validate response header values against their schema when validate_responses=True
Support the following schema properties for header validation:
type (integer, number, string, boolean)
enum
minimum / maximum (for integer/number)
minLength / maxLength (for string)
pattern (for string)
Handle type coercion: HTTP headers are strings, so an integer header with value "42" should be parsed to 42 before validation
Raise NonConformingResponseHeaders with a descriptive error message when validation fails
Support both OpenAPI 3.0 (headers use schema object) and Swagger 2.0 (headers use type directly)
Acceptance Criteria
Header with type: integer and non-integer value returns 500 error
Header with minimum: 0 and value -1 returns 500 error
Header with enum: ["A", "B"] and value "C" returns 500 error
Header with minLength: 5 and value "abc" returns 500 error
Valid header values pass validation without error
Works with both OpenAPI 3.0 and Swagger 2.0 specifications
Error message includes the header name and reason for failure
Technical Context
Response validation occurs in connexion/middleware/response_validation.py
The validate_required_headers method already iterates over header definitions
Request header validation in connexion/validators/parameter.py shows the pattern for validating parameter values
Swagger 2.0 header format: headers.X-Foo.type: integer
OpenAPI 3.0 header format: headers.X-Foo.schema.type: integer
For Submission - Test Specification
The tests should verify:
# Test 1: Integer header with string value fails
def test_response_header_invalid_integer_type(app):
"""Header defined as integer but handler returns string fails validation."""
# Spec: X-Total-Count with type: integer
# Handler returns: {"X-Total-Count": "not-a-number"}
# Expected: 500 status, error mentions "X-Total-Count"
# Test 2: Integer header below minimum fails
def test_response_header_below_minimum(app):
"""Header value below minimum constraint fails validation."""
# Spec: X-Total-Count with type: integer, minimum: 0
# Handler returns: {"X-Total-Count": "-5"}
# Expected: 500 status
# Test 3: Enum header with invalid value fails
def test_response_header_invalid_enum(app):
"""Header value not in enum fails validation."""
# Spec: X-Status with enum: ["OK", "ERROR"]
# Handler returns: {"X-Status": "INVALID"}
# Expected: 500 status
# Test 4: String header below minLength fails
def test_response_header_below_minlength(app):
"""Header value below minLength fails validation."""
# Spec: X-Request-Id with minLength: 10
# Handler returns: {"X-Request-Id": "short"}
# Expected: 500 status
# Test 5: Valid integer header passes (coercion works)
def test_response_header_valid_integer(app):
"""Valid integer header (as string) passes validation."""
# Spec: X-Total-Count with type: integer, minimum: 0
# Handler returns: {"X-Total-Count": "42"}
# Expected: 200 status, header present
# Test 6: Valid enum header passes
def test_response_header_valid_enum(app):
"""Valid enum header passes validation."""
# Spec: X-Status with enum: ["OK", "ERROR"]
# Handler returns: {"X-Status": "OK"}
# Expected: 200 status
# Test 7: Works with Swagger 2.0 spec
def test_response_header_validation_swagger2(swagger2_app):
"""Header validation works with Swagger 2.0 format."""
# Same logic but using Swagger 2.0 header format
# Test 8: Error message includes header name
def test_response_header_error_message(app):
"""Error response includes the header name that failed."""
# Check that response body contains "X-Total-Count" in detail
Summary
When
validate_responses=Trueis enabled, Connexion validates that required response headers are present, but does not validate that header values conform to their defined schema. This allows handlers to return headers with invalid values (wrong type, out of range, invalid enum) without triggering a validation error.Current Behavior
A handler can return:
Even when the spec defines X-Total-Count as an integer, Connexion accepts this and returns the response to the client.
Expected Behavior
When validate_responses=True, Connexion should validate response header values against their schema and raise NonConformingResponseHeaders if validation fails, returning a 500 error (similar to how missing required headers are handled).
Reproduction
OpenAPI 3.0 spec:
openapi: "3.0.0"
info:
title: Test API
version: "1.0"
paths:
/items:
get:
operationId: api.get_items
responses:
"200":
description: Success
headers:
X-Total-Count:
required: true
schema:
type: integer
minimum: 0
content:
application/json:
schema:
type: object
Handler:
def get_items():
return {"items": []}, 200, {"X-Total-Count": "invalid"}
Result: Returns 200 with invalid header
Expected: Returns 500 with validation error
Requirements
Validate response header values against their schema when validate_responses=True
Support the following schema properties for header validation:
type (integer, number, string, boolean)
enum
minimum / maximum (for integer/number)
minLength / maxLength (for string)
pattern (for string)
Handle type coercion: HTTP headers are strings, so an integer header with value "42" should be parsed to 42 before validation
Raise NonConformingResponseHeaders with a descriptive error message when validation fails
Support both OpenAPI 3.0 (headers use schema object) and Swagger 2.0 (headers use type directly)
Acceptance Criteria
Header with type: integer and non-integer value returns 500 error
Header with minimum: 0 and value -1 returns 500 error
Header with enum: ["A", "B"] and value "C" returns 500 error
Header with minLength: 5 and value "abc" returns 500 error
Valid header values pass validation without error
Works with both OpenAPI 3.0 and Swagger 2.0 specifications
Error message includes the header name and reason for failure
Technical Context
Response validation occurs in connexion/middleware/response_validation.py
The validate_required_headers method already iterates over header definitions
Request header validation in connexion/validators/parameter.py shows the pattern for validating parameter values
Swagger 2.0 header format: headers.X-Foo.type: integer
OpenAPI 3.0 header format: headers.X-Foo.schema.type: integer
For Submission - Test Specification
The tests should verify: