SonarSource/sonarqube · error · GradleException

${propName} is enabled but the sonarqube-unification path is

Error message

${propName} is enabled but the sonarqube-unification path is not configured.
Set sonarqubeUnificationPath in ~/.gradle/gradle.properties or export SONARQUBE_UNIFICATION_PATH.

What it means

The useLocalUnificationModule helper in settings.gradle lets developers substitute the remote sonarqube-unification dependency with a local checkout by setting a per-module property (e.g. useLocalUnification=true). If that flag is enabled but neither the sonarqubeUnificationPath gradle property nor the SONARQUBE_UNIFICATION_PATH env var provides the local checkout location, the settings evaluation fails with this GradleException.

Source

Thrown at settings.gradle:86

include 'sonar-markdown'
include 'sonar-plugin-api-impl'
include 'sonar-shutdowner'
include 'sonar-testing-harness'
include 'sonar-testing-ldap'
include 'sonar-ws'
include 'sonar-ws-generator'

// Registers a local composite build from the sonarqube-unification repo as a substitute for published artifacts.
// Set the property to true and optionally sonarqubeUnificationPath in ~/.gradle/gradle.properties.
// Falls back to the SONARQUBE_UNIFICATION_PATH environment variable if the Gradle property is not set.
// opts: group (default 'org.sonarsource.sonarqube'), projectPaths (map of name -> project path, default ':name')
def useLocalUnificationModule = { String propName, String subPath, List<String> modules, Map opts = [:] ->
  if (settings.hasProperty(propName) && settings[propName].toBoolean()) {
    def basePath = settings.hasProperty('sonarqubeUnificationPath')
      ? settings['sonarqubeUnificationPath']
      : System.getenv('SONARQUBE_UNIFICATION_PATH')
    if (!basePath) {
      throw new GradleException(
        "${propName} is enabled but the sonarqube-unification path is not configured.\n" +
        "Set sonarqubeUnificationPath in ~/.gradle/gradle.properties or export SONARQUBE_UNIFICATION_PATH."
      )
    }
    def group = opts.group ?: 'org.sonarsource.sonarqube'
    def groups = opts.groups ?: [:]
    def projectPaths = opts.projectPaths ?: [:]
    def dir = new File(basePath, subPath)
    println "Using local build [${propName}] from: ${dir.absolutePath}"
    if (opts.autoSubstitution) {
      // Preserve project-to-project variants for composites with mixed public and private modules.
      includeBuild(dir.absolutePath)
    } else {
      includeBuild(dir.absolutePath) {
        dependencySubstitution {
          modules.each { name ->
            def moduleGroup = groups[name] ?: group
            def projectPath = projectPaths[name] ?: ":${name}"

View on GitHub (pinned to 184c821202)

Solutions

  1. Set sonarqubeUnificationPath=/absolute/path/to/sonarqube-unification in ~/.gradle/gradle.properties
  2. Or export SONARQUBE_UNIFICATION_PATH=/absolute/path/to/sonarqube-unification in your shell/CI
  3. Or disable the local module by removing/setting the property (e.g. useLocalUnification=false) to fall back to the published artifact

Example fix

// before (gradle.properties)
useLocalUnification=true
// after (gradle.properties)
useLocalUnification=true
sonarqubeUnificationPath=/home/dev/src/sonarqube-unification
Defensive patterns

Strategy: validation

Validate before calling

// shell: fail fast if local unification flag set without path
if grep -q '^useLocalUnification=true' ~/.gradle/gradle.properties 2>/dev/null; then
  if [ -z "$SONARQUBE_UNIFICATION_PATH" ] && ! grep -q '^sonarqubeUnificationPath=' ~/.gradle/gradle.properties; then
    echo "Set sonarqubeUnificationPath or SONARQUBE_UNIFICATION_PATH" >&2
    exit 1
  fi
fi

Prevention

When it happens

Trigger: Adding e.g. useLocalUnification=true to ~/.gradle/gradle.properties (or a matching per-module flag) while SONARQUBE_UNIFICATION_PATH is not exported and sonarqubeUnificationPath is absent from gradle.properties.

Common situations: Switching machines and forgetting to re-export SONARQUBE_UNIFICATION_PATH; copying a colleague's gradle.properties with the flag but no path; running a build in a fresh CI container where only the flag was set.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/3cf95f7417e08c23. Report an issue: GitHub.