Skip to content

Field & @Deprecated descriptions silently dropped when they don't start with a letter #174

@levit0mer

Description

@levit0mer

Hi team,
First, thanks for graphql-kotlin-codegen, it's been a really nice fit for our Kotlin services and the codegen pipeline is genuinely lovely to work with. Wanted to flag a subtle issue that bit us this week and took a while to chase down because the codegen exits cleanly and the generated .kt files look fine at a glance.

TL;DR

Any GraphQL description whose first non-empty line does not start with an ASCII letter (e.g. it begins with (, [, a digit, `, @, an emoji, etc.) is silently dropped from the generated Kotlin annotations. The same code path also feeds @Deprecated("reason"), so deprecation reasons can silently become empty strings — which for us meant downstream partners lost the upgrade guidance entirely and we only noticed in QA.

Repro

I've put together a minimal reproduction here:

https://github.com/levit0mer/gqlkc-description-repro

git clone https://github.com/levit0mer/gqlkc-description-repro
cd gqlkc-description-repro
npm install
npx graphql-codegen --config codegen.yml
# inspect generated/Schema.kt vs expected/Schema.kt

The schema (excerpt) - these are the kind of descriptions we use across our booking/payments domain:

type Payment {
  """3D Secure verification status returned by the PSP."""
  threeDsStatus: String

  """(Deprecated) Use paymentVerification instead."""
  legacyVerification: String @deprecated(reason: "(internal) replaced by paymentVerification in v3")

  """`booking.id` of the parent itinerary."""
  bookingRef: String!
}

Expected Schema.kt

data class Payment(
  @GraphQLDescription("3D Secure verification status returned by the PSP.")
  val threeDsStatus: String? = null,

  @GraphQLDescription("(Deprecated) Use paymentVerification instead.")
  @Deprecated("(internal) replaced by paymentVerification in v3")
  val legacyVerification: String? = null,

  @GraphQLDescription("`booking.id` of the parent itinerary.")
  val bookingRef: String,
)

Actual Schema.kt

data class Payment(
  val threeDsStatus: String? = null,

  @Deprecated("")
  val legacyVerification: String? = null,

  val bookingRef: String,
)

Every description on those three fields is gone, and - the part that really worried us - the @Deprecated reason is now an empty string, so consumers of our generated SDK have no idea why the field is deprecated or what to migrate to.

I tried a few workarounds (escaping, leading whitespace, wrapping differently) but couldn't find a pattern that preserves the description when it starts with a non-letter. Happy to provide more details or a smaller repro if that helps narrow it down.

Versions:

  • @expediagroup/graphql-kotlin-codegen: 3.9.5
  • @graphql-codegen/cli: 6.1.1
  • node: 22.x
  • macOS 14

Thanks again - and apologies for the wall of text, just wanted to give you everything in one place.

Tomer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions