termux/termux-app · error · GradleException

The versionName '%s' is not a valid version as per semantic

Error message

The versionName '%s' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html.

What it means

Thrown by the validateVersionName Gradle task when android.defaultConfig.versionName does not match the SemVer 2.0.0 regular expression. The format required is 'major.minor.patch' with optional '-prerelease' and '+buildmetadata'. Any deviation (missing patch, leading zeros like '01.2.3', non-numeric components, bad prerelease syntax) fails validation and halts the build.

Source

Thrown at app/build.gradle:164

}

dependencies {
    testImplementation "junit:junit:4.13.2"
    testImplementation "org.robolectric:robolectric:4.10"
    coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
}

task versionName {
    doLast {
        print android.defaultConfig.versionName
    }
}

def validateVersionName(String versionName) {
    // https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
    // ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
    if (!java.util.regex.Pattern.matches("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?\$", versionName))
        throw new GradleException("The versionName '"  + versionName + "' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html.")
}

def downloadBootstrap(String arch, String expectedChecksum, String version) {
    def digest = java.security.MessageDigest.getInstance("SHA-256")

    def localUrl = "src/main/cpp/bootstrap-" + arch + ".zip"
    def file = new File(projectDir, localUrl)
    if (file.exists()) {
        def buffer = new byte[8192]
        def input = new FileInputStream(file)
        while (true) {
            def readBytes = input.read(buffer)
            if (readBytes < 0) break
            digest.update(buffer, 0, readBytes)
        }
        def checksum = new BigInteger(1, digest.digest()).toString(16)
        while (checksum.length() < 64) { checksum = "0" + checksum }
        if (checksum == expectedChecksum) {

View on GitHub (pinned to 3df69d1da1)

Solutions

  1. Set versionName to a strict 'MAJOR.MINOR.PATCH' string, e.g. '0.118.0'.
  2. Remove any 'v' prefix or non-numeric decorations from versionName.
  3. Avoid leading zeros in numeric identifiers (use 0, not 00/01).
  4. If using prerelease/build metadata, follow the allowed character sets in the regex.

Example fix

// before
def versionName = "v1.2"
// or
def versionName = "1.02.3"

// after (strict semver)
def versionName = "1.2.0"
Defensive patterns

Strategy: validation

Validate before calling

def SEMVER = ~/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-.+)?(?:\+.+)?$/
if (!(versionName ==~ SEMVER)) {
    throw new GradleException("versionName '${versionName}' is not valid semver")
}

Prevention

When it happens

Trigger: versionName is set to something like '1.2', 'v1.2.3', '1.02.3', '1.2.3.4', or contains characters not allowed in prerelease/build metadata segments. The regex is the official SemVer suggested one.

Common situations: Bumping the version and forgetting the patch number; prefixing with 'v'; using leading zeros in a numeric identifier; CI injecting a non-semver tag as versionName.

Related errors


AI-assisted analysis of termux/termux-app@3df69d1da1 (2026-08-13). Data as JSON: /api/errors/dd2561b757fbc012. Report an issue: GitHub.