{"record":{"id":"7997f948b2d70495","repo":"Tencent/matrix","slug":"need-signing-apk-but-the-path-of-apksigner-is-not","errorCode":null,"errorMessage":"Need signing apk but the path of apksigner is not specified!","messagePattern":"Need signing apk but the path of apksigner is not specified!","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTaskV2.kt","lineNumber":492,"sourceCode":"                throw GradleException(\"the path of Matrix-ApkChecker $pathOfApkChecker is not exist!\")\n            }\n        } else {\n            throw GradleException(\"the path of Matrix-ApkChecker not found!\")\n        }\n\n        // Validate path of Zipalign tool\n        if (isZipAlignEnabled) {\n            if (Util.isNullOrNil(pathOfZipAlign)) {\n                throw GradleException(\"Need zip align apk but the path of zipalign is not specified!\")\n            } else if (!File(pathOfZipAlign).exists()) {\n                throw GradleException(\"Need zipalign apk but $pathOfZipAlign is not exist!\")\n            }\n        }\n\n        // Validate path of signing\n        if (isSigningEnabled) {\n            if (Util.isNullOrNil(pathOfApkSigner)) {\n                throw GradleException(\"Need signing apk but the path of apksigner is not specified!\")\n            } else if (!File(pathOfApkSigner).exists()) {\n                throw GradleException(\"Need signing apk but $pathOfApkSigner is not exist!\")\n            } else if (AgpCompat.getSigningConfig(variant) == null) {\n                throw GradleException(\"Need signing apk but signingConfig is not specified!\")\n            }\n        }\n    }\n\n    private fun calculateResources(\n            setOfUnusedResources: Set<String>,\n            mapOfDuplicatedResources: Map<String, MutableSet<String>>,\n            mapOfResources: MutableMap<String, Int>,\n            resultOfResourcesGonnaRemoved: MutableMap<String, Int>,\n            resultOfDuplicatesReplacements: MutableMap<String, String>,\n            resultOfObfuscatedNames: MutableMap<String, String>\n    ) {\n\n        // Prepare unused resources","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTaskV2.kt#L474-L510","documentation":"Thrown by RemoveUnusedResourcesTaskV2.parametersInvalidation when signing is enabled (isSigningEnabled=true) but pathOfApkSigner is null or empty. The task needs the apksigner tool to re-sign the APK after removing resources, so it fails fast with a GradleException.","triggerScenarios":"Configuring matrix removeResourceConfig with useApkSign = true (signing enabled) without setting apksignerPath.","commonSituations":"Enabling signing for release builds but forgetting the apksigner path; migrating the Matrix config from an older project where the path was set; release-only configuration omitted on CI.","solutions":["Set matrix { removeResourceConfig { apksignerPath = \"${android.sdkDirectory}/build-tools/<ver>/apksigner\" } }.","Or disable signing (useApkSign = false) if the APK will be signed by another step.","On CI, ensure the SDK build-tools containing apksigner are installed and reference them dynamically."],"exampleFix":"// before\nmatrix {\n  removeResourceConfig {\n    useApkSign = true\n  }\n}\n// after\nmatrix {\n  removeResourceConfig {\n    useApkSign = true\n    apksignerPath = \"${android.sdkDirectory}/build-tools/33.0.1/apksigner\"\n  }\n}","handlingStrategy":"validation","validationCode":"def cfg = matrix.removeResourceConfig\nif (cfg?.useApkSign && (cfg.apksignerPath == null || cfg.apksignerPath.trim().isEmpty())) {\n  throw new GradleException(\"useApkSign requires apksignerPath\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set apksignerPath from ${android.sdkDirectory}/build-tools/<ver>/apksigner rather than by hand.","Keep signing and tool-path config in a shared convention plugin so all modules get it.","Verify config completeness in CI before running release builds."],"tags":["gradle","android","missing-config-value","signing"],"backgroundTag":"missing-config-value","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}