grape-swagger icon indicating copy to clipboard operation
grape-swagger copied to clipboard

Bug Report: `default` for array params (`type: [String]`) is incorrectly placed inside `items`

Open shamanomania opened this issue 10 months ago โ€ข 2 comments

Summary

When using the following parameter declaration in Grape:

optional :dns_servers, type: [String], desc: 'DNS servers', allow_blank: false, default: ["8.8.8.8", "8.8.4.4"]

grape-swagger generates an OpenAPI schema where the default value is incorrectly placed inside items, instead of being set at the array level. This causes the field to be interpreted as a nested array ([[value]]) in Swagger tools and breaks the expected structure.


๐Ÿ” Current Behavior (Incorrect)

Generated OpenAPI snippet:

dns_servers:
  type: array
  items:
    type: string
    default: ["8.8.8.8", "8.8.4.4"]  # โŒ incorrect placement โ€” default on items must be a single value, not an array

โš ๏ธ Swagger Editor interprets this as:

"dns_servers": [
  ["8.8.8.8", "8.8.4.4"]
]

Which is not the intended behavior, and breaks compatibility with clients, documentation, and tools.


โœ… Expected Behavior

The correct OpenAPI output should look like this:

dns_servers:
  type: array
  items:
    type: string
  default:
    - "8.8.8.8"
    - "8.8.4.4"

This correctly documents a default array of strings, not a nested array of arrays.


๐Ÿงช Minimal Reproducible Example (Swagger Editor โ€” OpenAPI 2.0 - https://editor.swagger.io)

swagger: "2.0"
info:
  title: DNS Servers Example
  version: "1.0"
paths:
  /example:
    post:
      parameters:
        - in: body
          name: postV1Organization
          required: true
          schema:
            type: object
            properties:
              dns_servers:
                type: array
                items:
                  type: string
                  default: ["8.8.8.8", "8.8.4.4"]  # โŒ incorrect โ€” invalid type, causes nested array
      responses:
        200:
          description: OK

โœ… Correct version for comparison:

dns_servers:
  type: array
  items:
    type: string
  default:
    - "8.8.8.8"
    - "8.8.4.4"

๐Ÿ“š Specification Insights (OpenAPI & JSON Schema)

  • OpenAPI 3.0 Schema Object:

    The default value represents what would be assumed by the consumer of the input if one is not provided. It MUST conform to the defined type for the schema object.

  • Swagger 2.0 Items Object:

    The value MUST conform to the defined type for the data type.

  • JSON Schema - enum:

    The instance MUST be equal to one of the values in the array.

  • JSON Schema - default:

    It is RECOMMENDED that a default value be valid against the associated schema.


๐Ÿ”Ž Why this matters

  • Placing default inside items implies a per-item default, which is not meaningful for array parameters.
  • Putting an array value as the default inside items (which expects a scalar) leads to nested arrays and invalid schemas.
  • This issue causes confusion in docs, misbehavior in tools, and breaks conformity with OpenAPI semantics.

๐Ÿ”— Related


๐Ÿ“ฆ Version Info

  • ruby: 3.3.4
  • grape: 2.3.0
  • grape-swagger: 2.1.2

๐Ÿ’ก Suggestion: when generating schemas from type: [String] with a default, grape-swagger should ensure the default is set at the array level โ€” not inside items, and that its type conforms to OpenAPI expectations.

shamanomania avatar Apr 23 '25 16:04 shamanomania

@dblock Hi! What do you think about the issue?

shamanomania avatar Apr 28 '25 13:04 shamanomania

I am mostly fly-by here, but looks like a bug! If you know how to fix it, please PR.

dblock avatar May 03 '25 12:05 dblock