Skip to content

[BUG] Inline schema with doc comment creates allOf with empty object missing additionalProperties: false #1507

Description

@JMLX42

Bug Description

When using #[schema(inline)] on a field that has a doc comment, utoipa generates an allOf composition where:

  1. First item: the inlined schema (correctly has additionalProperties: false from #[serde(deny_unknown_fields)])
  2. Second item: an empty object with just the field's doc comment as description (missing additionalProperties: false)

This causes OpenAPI code generators to incorrectly add additional_properties: HashMap<String, Value> to generated structs.

Minimal Reproducible Example

use serde::{Serialize, Deserialize};
use utoipa::ToSchema;

/// An orthographic camera containing properties to create an orthographic projection matrix.
#[derive(Debug, Clone, Default, ToSchema, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct OrthographicCamera {
    pub xmag: f32,
    pub ymag: f32,
    pub zfar: f32,
    pub znear: f32,
}

#[derive(Debug, Clone, Default, Serialize, ToSchema)]
pub struct Camera {
    /// An orthographic camera. This property **MUST NOT** be defined when `perspective` is defined.
    #[schema(inline)]
    pub orthographic: Option<OrthographicCamera>,
}

Generated OpenAPI Schema

"orthographic": {
  "allOf": [
    {
      "type": "object",
      "description": "An orthographic camera containing properties to create an orthographic projection matrix.",
      "required": ["xmag", "ymag", "zfar", "znear"],
      "properties": {
        "xmag": { "type": "number", "format": "float" },
        "ymag": { "type": "number", "format": "float" },
        "zfar": { "type": "number", "format": "float" },
        "znear": { "type": "number", "format": "float" }
      },
      "additionalProperties": false
    },
    {
      "type": "object",
      "description": "An orthographic camera. This property **MUST NOT** be defined when `perspective` is defined."
    }
  ]
}

Expected Behavior

The second allOf item should either:

  1. Not be an empty object - put the description at the allOf level instead:
"orthographic": {
  "description": "An orthographic camera. This property **MUST NOT** be defined when `perspective` is defined.",
  "allOf": [
    {
      "type": "object",
      "properties": { ... },
      "additionalProperties": false
    }
  ]
}
  1. Or include additionalProperties: false to match the inlined schema:
{
  "type": "object",
  "description": "...",
  "additionalProperties": false
}

Impact

OpenAPI code generators like openapi-generator check each allOf item for additionalProperties. When an item has no properties and no additionalProperties: false, generators like the Rust generator treat it as a free-form object and add:

#[serde(flatten)]
pub additional_properties: std::collections::HashMap<String, serde_json::Value>,

This breaks type safety and contradicts the deny_unknown_fields intent.

Environment

  • utoipa version: latest
  • Rust version: stable
  • OpenAPI spec version: 3.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions