Skip to content

[BUG][scala-sttp] Optional header values incorrectly serialized as "Some(value)"` #21602

@gseeds-intercax

Description

@gseeds-intercax

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

[scala-sttp] Invalid header value produced for optional headers when present - Some(value)

When a header is defined as not required, the code generated by the scala-sttp generator creates that parameter as an Option[T], but one when it creates the header, it calls the toString method on that option. If the value is present, this results in a string like Some(actual_string_value)

Snippet

paths:
  /ping:
    get:
      summary: Ping with optional header
      operationId: getPing
      parameters:
        - name: X-Optional-Header
          in: header
          required: false
          schema:
            type: string

produces

  def getPing(xOptionalHeader: Option[String] = None
): Request[Either[ResponseException[String, Exception], String], Any] =
    basicRequest
      .method(Method.GET, uri"$baseUrl/ping")
      .contentType("application/json")
      .header("X-Optional-Header", xOptionalHeader.toString)
      .response(asJson[String])

}

Calling toString on an Option[String] does not return the value of the Option, but instead returns a string with "Some()" around the value. This is not generally a valid value for the header.

openapi-generator version

Issue found in 7.4.0

OpenAPI declaration file content or url
openapi: 3.0.0
info:
  title: Optional Header Test
  version: 1.0.0

paths:
  /ping:
    get:
      summary: Ping with optional header
      operationId: getPing
      parameters:
        - name: X-Optional-Header
          in: header
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: string
Generation Details

I'm not sure of the config structure that would be useful here. Ran the CLI with -g scala-sttp like

openapi-generator-cli generate -g scala-sttp -i optional-header.yaml -o client

Steps to reproduce
  1. Using openapi-generator cli, generate client code from the supplied spec for scala-sttp
  2. Confirm the generated client code contains the DefaultApi class with method getPing
  3. Use the provided test code or similar below to get a request from the getPing method with the optional header set to "header value"
  4. Confirm that the header's value is not "header value", but instead "Some(header value)"

Test code example

  val defaultApi = DefaultApi()
  val request = defaultApi.getPing(Some("header value"))
  print(request.toCurl)

Result:

curl \
  --request GET \
  --url 'http://localhost/ping' \
  --header 'Content-Type: application/json' \
  --header 'X-Optional-Header: Some(header value)' \
  --location \
  --max-redirs 32
Related issues/PRs

This issue appears related to #11991, in which a toString was added to scala-sttp/paramCreation. This change fixes an issue with other header types, but for Option[String] it breaks the functionality.

Suggest a fix

The issue appears to be line 1 of scala-sttp/paramCreation.mustache, where header parameter has toString appended.

"{{baseName}}", {{#isContainer}}ArrayValues({{{paramName}}}{{#collectionFormat}}, {{collectionFormat.toUpperCase}}{{/collectionFormat}}){{/isContainer}}{{^isContainer}}{{{paramName}}}{{/isContainer}}.toString

  • [ ]

  • [ ]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions