Tencent/matrix · error · GradleException

Need zip align apk but the path of zipalign is not…

Error message

Need zip align apk but the path of zipalign is not specified!

What it means

Thrown by RemoveUnusedResourcesTaskV2.parametersInvalidation during Gradle parameter validation. The task is configured to zip-align the resulting APK (isZipAlignEnabled=true) but no path to the zipalign tool was provided, so it aborts before doing any work via GradleException. The zipalign binary is required to align the uncompressed entries of the APK before it can be shipped.

Solutions

  1. Set matrix { removeResourceConfig { zipAlignPath = "/path/to/android-sdk/build-tools/<ver>/zipalign" } } in build.gradle.
  2. Or set zipAlignEnabled = false if alignment is not required for this build.
  3. Verify the path resolves on the build machine (CI may have a different SDK layout); prefer locating it dynamically from android.sdkDirectory/build-tools.

Example fix

// before
matrix {
  removeResourceConfig {
    zipAlignEnabled = true
  }
}
// after
matrix {
  removeResourceConfig {
    zipAlignEnabled = true
    zipAlignPath = "${android.sdkDirectory}/build-tools/33.0.1/zipalign"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

def cfg = matrix.extensions.findByName('matrix')?.removeResourceConfig
if (cfg?.zipAlignEnabled && (cfg.zipAlignPath == null || cfg.zipAlignPath.trim().isEmpty())) {
  throw new GradleException("zipAlignEnabled requires zipAlignPath to be set")
}

Prevention

When it happens

Trigger: Running the removeUnusedResources task with matrix removeResourceConfig zipAlignEnabled = true while the extension property zipAlignPath (pathOfZipAlign) is left null/empty.

Common situations: Developers enable zipAlign in the Matrix config but forget to point zipAlignPath at the Android SDK build-tools zipalign binary (e.g. $ANDROID_HOME/build-tools/<version>/zipalign); also common on CI machines where build-tools versions changed and the hardcoded path is stale.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/78f4a84c41a13141. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTaskV2.kt:483

            }
        }
    }

    private fun parametersInvalidation() {

        // Validate path of ApkChecker tool
        if (!Util.isNullOrNil(pathOfApkChecker)) {
            if (!File(pathOfApkChecker).exists()) {
                throw GradleException("the path of Matrix-ApkChecker $pathOfApkChecker is not exist!")
            }
        } else {
            throw GradleException("the path of Matrix-ApkChecker not found!")
        }

        // Validate path of Zipalign tool
        if (isZipAlignEnabled) {
            if (Util.isNullOrNil(pathOfZipAlign)) {
                throw GradleException("Need zip align apk but the path of zipalign is not specified!")
            } else if (!File(pathOfZipAlign).exists()) {
                throw GradleException("Need zipalign apk but $pathOfZipAlign is not exist!")
            }
        }

        // Validate path of signing
        if (isSigningEnabled) {
            if (Util.isNullOrNil(pathOfApkSigner)) {
                throw GradleException("Need signing apk but the path of apksigner is not specified!")
            } else if (!File(pathOfApkSigner).exists()) {
                throw GradleException("Need signing apk but $pathOfApkSigner is not exist!")
            } else if (AgpCompat.getSigningConfig(variant) == null) {
                throw GradleException("Need signing apk but signingConfig is not specified!")
            }
        }
    }

    private fun calculateResources(

View on GitHub (pinned to 3b8293bd65)