Tencent/matrix · error · GradleException

Need zipalign apk but $pathOfZipAlign is not exist!

Error message

Need zipalign apk but $pathOfZipAlign is not exist!

What it means

Thrown by RemoveUnusedResourcesTaskV2.parametersInvalidation when zip align is enabled and pathOfZipAlign is set, but the file at that path does not exist. The task refuses to run rather than failing later during execution of zipalign.

Solutions

  1. Correct zipAlignPath to an existing zipalign binary: ls $ANDROID_HOME/build-tools/*/zipalign and pick the installed version.
  2. Install the matching build-tools platform via the SDK manager so the configured path exists.
  3. Disable zip alignment (zipAlignEnabled = false) if not needed.
  4. Generate the path dynamically from android.sdkDirectory instead of hardcoding.

Example fix

// before
zipAlignPath = "/opt/android-sdk/build-tools/30.0.3/zipalign" // directory removed
// after
zipAlignPath = file("${android.sdkDirectory}/build-tools/${project.buildToolsVersion}/zipalign").absolutePath
Defensive patterns

Strategy: validation

Validate before calling

def zipalign = file("${android.sdkDirectory}/build-tools/${project.buildToolsVersion}/zipalign")
if (matrix.removeResourceConfig.zipAlignEnabled && !zipalign.exists()) {
  throw new GradleException("zipalign not found at ${zipalign}; install matching build-tools")
}

Prevention

When it happens

Trigger: Running removeUnusedResources with zipAlignEnabled=true and a non-empty zipAlignPath that points to a nonexistent file (typo, wrong SDK version directory, binary removed after SDK update).

Common situations: Hardcoded build-tools path after upgrading the Android SDK (e.g. build-tools/30.0.3 no longer installed); team members with different SDK versions; CI images missing specific build-tools revisions.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

    }

    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(
            setOfUnusedResources: Set<String>,
            mapOfDuplicatedResources: Map<String, MutableSet<String>>,

View on GitHub (pinned to 3b8293bd65)