Skip to content

fix: handle empty schemas as "any" type instead of error#1585

Merged
ernado merged 3 commits intoogen-go:mainfrom
lanej:fix/empty-schema-handling
Nov 25, 2025
Merged

fix: handle empty schemas as "any" type instead of error#1585
ernado merged 3 commits intoogen-go:mainfrom
lanej:fix/empty-schema-handling

Conversation

@lanej
Copy link
Contributor

@lanej lanej commented Nov 25, 2025

Summary

Implements context-aware handling for empty media type objects in OpenAPI specs. Responses with missing schemas generate jx.Raw (flexible), requests with missing schemas error (conservative).

Fixes #10

The Rule

Empty schema in response  → jx.Raw     (✅ generate)
Empty schema in request   → Error      (❌ reject)

Following Postel's Law: be liberal in what you accept, conservative in what you send.

Why This Approach?

Missing schema ≠ "accepts anything" (per OpenAPI spec maintainer)

  • For responses: Server controls the shape. Client needs jx.Raw to handle varying/unknown structures (errors, legacy APIs, vendor-specific fields)
  • For requests: Client shouldn't guess. Missing schema is a spec authoring issue that should be caught, not silently accepted

Users wanting arbitrary request bodies should explicitly specify schema: true (JSON Schema's "any" type) rather than omit the schema field.

Examples

Response (works):

responses:
  default:
    content:
      application/json: {}  # ✅ Generates jx.Raw
func (h Handler) CreateShipment(ctx context.Context) (jx.Raw, error)
//                                                     ^^^^^^ any JSON

Request (errors):

requestBody:
  content:
    application/json: {}  # ❌ Error: "empty schema in request body"

Testing

Guarantees:

  • ✅ Response handlers generate with valid jx.Raw return types
  • ✅ Request specs fail fast with actionable error message
  • ✅ Zero regressions (all existing tests pass)
  • ✅ 100% coverage on new conditional logic

Impact

Unblocks code generation for real-world APIs (default error responses, flexible endpoints, legacy specs) while preventing unspecified client behavior.

Empty schemas (nil schema in OpenAPI specs) represent "any valid JSON value"
according to JSON Schema specification. Previously these were treated as
errors, but they should be handled as ir.Any (jx.Raw in Go).

This commonly occurs in request/response bodies with content but no schema:
{"content": {"application/json": {}}}

Changes:
- Modified schema_gen.go to return ir.Any(nil) for nil schemas
- Added documentation explaining empty schema semantics
- Aligned with existing array handling (line 431)
- Added regression test TestSchemaGenNilSchema
- Moved response_content_schema.json from negative to positive testdata

Fixes #10
@lanej lanej marked this pull request as draft November 25, 2025 00:38
Empty schemas (missing schema field in OpenAPI media type objects) now have
context-aware handling:

**Responses**: Generate jx.Raw (any JSON value)
- Allows clients to handle unknown JSON structures from servers
- Solves issue #10 for default error responses and flexible APIs
- Consistent with JSON Schema spec (empty schema = any JSON)

**Requests**: Return error "empty schema in request body"
- Prevents clients from sending arbitrary data without spec guidance
- More conservative approach - requires explicit schema or ignore flag
- Avoids over-permissive APIs where spec doesn't define structure

Changes:
- Added `request bool` field to `generateSchemaOverride` and `schemaGen`
- Modified `generate2()` to check context before handling nil schemas
- Updated `generateContents()` to pass request flag via override
- Split test into separate Response/Request test cases
- Updated test data to use response-only empty schema test

Fixes #10
@lanej lanej marked this pull request as ready for review November 25, 2025 01:10
@ernado ernado merged commit 5532ef3 into ogen-go:main Nov 25, 2025
15 checks passed
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.

2 participants