Skip to content

Gradle: Incorrect version replacement in Kotlin DSL when artifacts share Group ID and VersionΒ #14214

@ramonibz

Description

@ramonibz

Is there an existing issue for this?

  • I have searched the existing issues

Package ecosystem

Gradle (Kotlin DSL - build.gradle.kts)

Package manager version

Gradle

Language version

Gradle 8.14.3

Description

We are experiencing a critical bug where Dependabot updates unrelated dependencies in our build.gradle.kts file. This happens when two different artifacts share the same Group ID and the same current version string.

When Dependabot attempts to update Dependency A, it incorrectly replaces the version string of Dependency B as well, even though Dependency B was not the target of the update (and often the new version does not exist for B, breaking the build).

Steps to Reproduce

  1. Have a build.gradle.kts with two dependencies sharing the same Group ID and version:

    dependencies {
        // Dependency NOT meant to be updated (Dependency B) version 4.0.0-RC1 is the latest available version for this lib
        implementation("com.adevinta.motor:backend-common--lib-instrumentation:4.0.0-RC1")
        
        // Dependency MEANT to be updated (Dependency A - update available to 4.0.0)
        implementation("com.adevinta.motor:feign-error-handler:4.0.0-RC1")
    }
  2. Wait for Dependabot to trigger an update for com.adevinta.motor:feign-error-handler from 4.0.0-RC1 to 4.0.0.

  3. Expected behavior: Only feign-error-handler is updated.

  4. Actual behavior: Both lines are updated to 4.0.0.

Logs

The logs show that Dependabot intends to update only the specific artifact:

+------------------------------------------------------------------------------+
|                     Changes to Dependabot Pull Requests                      |
+---------+--------------------------------------------------------------------+
| created | com.adevinta.motor:feign-error-handler ( from 4.0.0-RC1 to 4.0.0 ) |
+---------+--------------------------------------------------------------------+

However, the resulting Pull Request contains file changes for other artifacts sharing the group com.adevinta.motor and version 4.0.0-RC1 that are not listed in the change summary.

Analysis & Suspected Root Cause

I believe I've located the issue in dependabot-core/gradle/lib/dependabot/gradle/file_updater.rb.

In the original_buildfile_declarations method, specifically inside the loop that iterates over the file lines (around lines 224-250), there is a regex/filter logic that seems too permissive:

# dependabot/gradle/file_updater.rb

if dependency.name.include?(":")
  dep_parts = dependency.name.split(":")
  
  # THE ISSUE IS HERE: using || (OR) instead of && (AND) or a stricter check
  next false unless line.include?(T.must(dep_parts.first)) || line.include?(T.must(dep_parts.last))

The logic line.include?(group) || line.include?(artifact) causes a false positive.

In my case:

  • Target: com.adevinta.motor:feign-error-handler
  • Line in file: implementation("com.adevinta.motor:backend-common--lib-instrumentation:4.0.0-RC1")

Since the line contains the group com.adevinta.motor, the condition evaluates to true. Consequently, the regex fallback logic (which likely looks for the version string 4.0.0-RC1 nearby) finds a match and incorrectly replaces the version on the wrong line.

Suggested Fix

The condition should verify both the group AND the artifact, or look for the concatenated string group:artifact to ensure it is editing the correct line.

Related issues / PRs

I've seen a related issue which was fixed in this PR but seems like the PR was merged and later rolled back do the fix was never applied

dependabot.yml content

version: 2
registries:
maven-codeartifact:
type: maven-repository
url: https://motor-internal-748380947066.d.codeartifact.eu-west-1.amazonaws.com/maven/libs-release/
username: aws
password: ${{secrets.CODEARTIFACT_AUTH_TOKEN}}
updates:

  • package-ecosystem: "gradle"
    directory: "/"
    registries:
    • maven-codeartifact
      schedule:
      interval: "weekly"
      day: "tuesday"
      time: "03:59"
      timezone: "Europe/Madrid"
      reviewers:
    • "scmspain/es-mt-c2b"
      commit-message:
      prefix: "chore"
      include: scope
      labels:
    • "auto-rebase"
    • "auto-merge:rebase"
    • "Ready to Merge"

Updated dependency

No response

What you expected to see, versus what you actually saw

Having this in build.gradle.kts

dependencies {
    implementation("com.adevinta.motor:backend-common--lib-instrumentation:4.0.0-RC1")
    implementation("com.adevinta.motor:feign-error-handler:4.0.0-RC1")
}

When a new release with version 4.0.0 is available for com.adevinta.motor:feign-error-handler but latest release available of com.adevinta.motor:backend-common--lib-instrumentation is 4.0.0-RC1

I expect Dependabot to update the file with:

dependencies {
    implementation("com.adevinta.motor:backend-common--lib-instrumentation:4.0.0-RC1")
    implementation("com.adevinta.motor:feign-error-handler:4.0.0")
}

But Dependabot ends up updating both libraries incorrectly:

   dependencies {
       implementation("com.adevinta.motor:backend-common--lib-instrumentation:4.0.0")
       implementation("com.adevinta.motor:feign-error-handler:4.0.0")
   }

Native package manager behavior

No response

Images of the diff or a link to the PR, issue, or logs

It's a private repo, i attach screenshot
Image

Smallest manifest that reproduces the issue

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions