Skip to content

[BUG][scala-sttp][circe] Decoder[Double] rejects NaN/Infinity JSON strings  #23610

Description

@nikhilsu

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
Description

The scala-sttp generator (circe JSON library) produces a Decoder[Double] that rejects JSON strings "NaN", "Infinity", and "-Infinity". Many real-world JSON APIs serialize Double.NaN / Double.POSITIVE_INFINITY / Double.NEGATIVE_INFINITY as quoted strings rather than unquoted JSON tokens. Jackson defaults to that behavior. Clients generated with scala-sttp + circe fail to deserialize any response containing such values.

openapi-generator version

7.22.0-SNAPSHOT (latest master). Also reproduces on 7.20.0 and 7.21.0.

OpenAPI declaration file content or url
openapi: 3.0.3
info: { title: test, version: 1.0.0 }
paths:
  /metric:
    get:
      operationId: getMetric
      responses:
        '200':
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Metric' }
components:
  schemas:
    Metric:
      type: object
      properties:
        value:
          type: number
          format: double

A real response from the server: {"value": "NaN"} (string — what Jackson/Flink emit by default).

Generation Details
openapi-generator-cli generate \
  -i spec.yaml \
  -g scala-sttp \
  --additional-properties jsonLibrary=circe \
  -o out
Steps to reproduce
  1. Generate a client as above.
  2. Invoke getMetric against a server that returns {"value": "NaN"}.
  3. Observe DecodingFailure: Double thrown by circe.

Actual: sttp.client3.DeserializationException[io.circe.DecodingFailure] — the response body fails to parse.

Expected: The decoder accepts "NaN" / "Infinity" / "-Infinity" as strings and maps them to Double.NaN / Double.PositiveInfinity / Double.NegativeInfinity.

Related issues/PRs

No existing issue/PR for this specific behavior in scala-sttp. Related context: Jackson's ALLOW_NON_NUMERIC_NUMBERS defaults allow producing these string values on the server side.

Suggest a fix

Add a tolerant Decoder[Double] to additionalTypeSerializers.mustache:

implicit final lazy val NanTolerantDoubleDecoder: Decoder[Double] =
  Decoder.decodeDouble.or(Decoder.decodeString.emap {
    case "NaN" => Right(Double.NaN)
    case "Infinity" => Right(Double.PositiveInfinity)
    case "-Infinity" => Right(Double.NegativeInfinity)
    case s => Left(s"Cannot decode '$s' as Double")
  })

This keeps strict numeric parsing as the default path and only falls back to string decoding for the three non-finite values. Scala 2.12-compatible via circe's Decoder.or combinator and .emap. I'll open a PR with this + a unit test + sample regen.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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