Tencent/matrix · error · GradleException
need sign apk but apksigner $apksigner was not exist!
Error message
need sign apk but apksigner $apksigner was not exist!
What it means
This variant of the signing configuration check fires when an `apksigner` path WAS provided but the file does not exist on disk. The task verifies `File(apksigner).exists()` before signing the shrunk APK and fails fast with the configured path included in the message.
Solutions
- Point `apksigner` at an existing build-tools binary on the current machine: `$ANDROID_HOME/build-tools/<version>/apksigner` (apksigner.bat on Windows).
- Run `ls` on the configured path to confirm it exists and is executable; update the config.
- Install the required build-tools version via the Android SDK manager if it is missing.
- Or set `needSign = false` if re-signing is not needed.
Example fix
// before apksigner = "/Users/alice/Library/Android/sdk/build-tools/28.0.3/apksigner" // deleted by SDK upgrade // after (check existing version first) apksigner = "/Users/alice/Library/Android/sdk/build-tools/34.0.0/apksigner"
Defensive patterns
Strategy: validation
Validate before calling
def apksigner = new File("${System.getenv('ANDROID_HOME')}/build-tools/34.0.0/apksigner")
assert apksigner.exists() : "apksigner missing at ${apksigner}" Type guard
def apksignerExists = { String p -> p != null && new File(p).exists() } Try / catch
try { ... } catch (GradleException e) { if (e.message.contains('was not exist')) { logger.error('Fix apksigner path: ' + e.message) } throw e } Prevention
- Resolve apksigner path dynamically from the SDK location and an existing build-tools version.
- Re-verify the path after SDK/build-tools upgrades.
- Check path exists on every CI agent, not just local machines.
When it happens
Trigger: `needSign = true`, `apksigner` is a non-empty string, but `File(apksigner).exists()` returns false when `removeUnusedResources` executes.
Common situations: Hard-coded path from another machine or CI image; SDK upgraded and the old build-tools directory was deleted; relative path resolved against a different working directory; typo in path or missing executable extension on Windows.
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
- Need signing apk but $pathOfApkSigner is not exist!
- apksigner returned with status: $ret
- need sign apk but apksigner not found!
- need sign apk but signingConfig not found!
- process.errorStream.bufferedReader().readLines().joinTo(Stri…
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/bdd4051142f728b9.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTask.kt:130
typeName = typeName.substring(0, index)
}
resourceName = "R.$typeName.$resName"
}
}
return resourceName
}
private fun removeUnusedResources(
originalApk: String,
rTxtFile: String,
signingConfig: SigningConfig?) {
// Check configurations
if (needSign) {
if (Util.isNullOrNil(apksigner)) {
throw GradleException("need sign apk but apksigner not found!");
} else if (!File(apksigner).exists()) {
throw GradleException("need sign apk but apksigner $apksigner was not exist!");
} else if (signingConfig == null) {
throw GradleException("need sign apk but signingConfig not found!");
}
}
var zipOutputStream: ZipOutputStream? = null
try {
try {
val inputFile = File(originalApk)
for (res in ignoreRes) {
ignoreResources.add(Util.globToRegexp(res))
}
val iterator = unusedResources.iterator()
while (iterator.hasNext()) {
val res = iterator.next()View on GitHub (pinned to 3b8293bd65)