{"record":{"id":"2bf22c8b47e09e30","repo":"termux/termux-app","slug":"unsupported-termux-package-variant-s","errorCode":null,"errorMessage":"Unsupported TERMUX_PACKAGE_VARIANT \"%s\"","messagePattern":"Unsupported TERMUX_PACKAGE_VARIANT \"(.+?)\"","errorType":"validation","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"app/build.gradle","lineNumber":234,"sourceCode":"}\n\ntask downloadBootstraps() {\n    doLast {\n        def packageVariant = project.ext.packageVariant\n        if (packageVariant == \"apt-android-7\") {\n            def version = \"2026.02.12-r1\" + \"%2B\" + \"apt.android-7\"\n            downloadBootstrap(\"aarch64\", \"ea2aeba8819e517db711f8c32369e89e7c52cee73e07930ff91185e1ab93f4f3\", version)\n            downloadBootstrap(\"arm\", \"a38f4d3b2f735f83be2bf54eff463e86dc32a3e2f9f861c1557c4378d249c018\", version)\n            downloadBootstrap(\"i686\", \"f5bc0b025b9f3b420b5fcaeefc064f888f5f22a0d6fd7090f4aac0c33eb3555b\", version)\n            downloadBootstrap(\"x86_64\", \"b7fd0f2e3a4de534be3144f9f91acc768630fc463eaf134ab2e64c545e834f7a\", version)\n        } else if (packageVariant == \"apt-android-5\") {\n            def version = \"2022.04.28-r6\" + \"+\" + packageVariant\n            downloadBootstrap(\"aarch64\", \"913609d439415c828c5640be1b0561467e539cb1c7080662decaaca2fb4820e7\", version)\n            downloadBootstrap(\"arm\", \"26bfb45304c946170db69108e5eb6e3641aad751406ce106c80df80cad2eccf8\", version)\n            downloadBootstrap(\"i686\", \"46dcfeb5eef67ba765498db9fe4c50dc4690805139aa0dd141a9d8ee0693cd27\", version)\n            downloadBootstrap(\"x86_64\", \"615b590679ee6cd885b7fd2ff9473c845e920f9b422f790bb158c63fe42b8481\", version)\n        } else {\n            throw new GradleException(\"Unsupported TERMUX_PACKAGE_VARIANT \\\"\" + packageVariant + \"\\\"\")\n        }\n    }\n}\n\nafterEvaluate {\n    android.applicationVariants.all { variant ->\n        variant.javaCompileProvider.get().dependsOn(downloadBootstraps)\n    }\n}\n","sourceCodeStart":216,"sourceCodeEnd":244,"githubUrl":"https://github.com/termux/termux-app/blob/3df69d1da197dd9bd71a3bafd902dffd720576b4/app/build.gradle#L216-L244","documentation":"This GradleException is thrown by the `downloadBootstraps` task in app/build.gradle when the `TERMUX_PACKAGE_VARIANT` environment variable resolves to a value other than the two recognized variants (`apt-android-7` or `apt-android-5`). The variant selects which prebuilt bootstrap zip (apt package set) is downloaded and bundled into the APK, so an unknown variant has no corresponding checksums or download URLs and the build cannot proceed safely. It fails the build immediately rather than silently bundling the wrong bootstrap, which would crash the app at startup (TermuxBootstrap.setTermuxPackageManagerAndVariant throws a RuntimeException for unknown variants).","triggerScenarios":"The error triggers when (a) `TERMUX_PACKAGE_VARIANT` is exported in the shell/CI environment to a typo'd or unsupported string (e.g. `apt-adroid-7`, `apt-android-8`, `pacman-android-7`), or (b) the variable is set to an empty string (`TERMUX_PACKAGE_VARIANT=\"\"`), since the Groovy Elvis operator `?:` only falls back to the default when the env var is unset, not when it is empty. It also triggers if a new variant is introduced in the Java side (TermuxBootstrap.PackageVariant) but the Gradle if/else chain is not updated with matching download entries.","commonSituations":"Typical contexts: a developer copies a build command from an outdated wiki that references a variant that was removed or renamed; a CI pipeline inherits `TERMUX_PACKAGE_VARIANT` from a global secret/template with a stale value; someone experiments with the pacman-based variant naming before Gradle support is added; an empty-string export (`export TERMUX_PACKAGE_VARIANT=`) defeats the Elvis default and lands in the else branch.","solutions":["Check the current value: run `echo \"$TERMUX_PACKAGE_VARIANT\"` in the build shell. If it is empty, unset it with `unset TERMUX_PACKAGE_VARIANT` so the Groovy Elvis operator falls back to the default `apt-android-7`.","If you intentionally set the variable, correct it to one of the two supported values: `export TERMUX_PACKAGE_VARIANT=apt-android-7` (API 24+, default) or `export TERMUX_PACKAGE_VARIANT=apt-android-5` (legacy API 21+).","In CI, audit the pipeline/secret that injects `TERMUX_PACKAGE_VARIANT` and align it with a supported value, or remove the injection entirely to use the default.","If you are adding a genuinely new variant, update three places in lockstep: the `if/else` chain in `downloadBootstraps` (add a branch with download URLs + SHA-256 checksums), the Java enum in `com.termux.shared.termux.TermuxBootstrap.PackageVariant`, and the documentation comment listing supported values at app/build.gradle:11."],"exampleFix":"// before\nexport TERMUX_PACKAGE_VARIANT=\"apt-android-8\"\n./gradlew assembleRelease\n// after\nunset TERMUX_PACKAGE_VARIANT   # or: export TERMUX_PACKAGE_VARIANT=apt-android-7\n./gradlew assembleRelease","handlingStrategy":"validation","validationCode":"// Pre-build check (Groovy, in app/build.gradle ext block or a CI script)\ndef packageVariant = System.getenv(\"TERMUX_PACKAGE_VARIANT\") ?: \"apt-android-7\"\ndef supported = [\"apt-android-7\", \"apt-android-5\"] as Set\nif (!(packageVariant in supported)) {\n    throw new GradleException(\n        \"Unsupported TERMUX_PACKAGE_VARIANT \\\"\" + packageVariant + \"\\\". \" +\n        \"Supported: \" + supported.join(\", \") + \". \" +\n        \"Unset the env var to use the default, or fix the value.\")\n}","typeGuard":"// Shell guard — call before invoking gradle\ncheck_variant() {\n  local v=\"${TERMUX_PACKAGE_VARIANT:-apt-android-7}\"\n  case \"$v\" in\n    apt-android-7|apt-android-5) return 0 ;;\n    \"\") return 0 ;;   # treat truly-unset as OK (Elvis handles it)\n    *) echo \"Unsupported TERMUX_PACKAGE_VARIANT: '$v'\" >&2; return 1 ;;\n  esac\n}","tryCatchPattern":"// Gradle task wrapping the variant check\ntask checkPackageVariant() {\n    doLast {\n        def v = project.ext.packageVariant\n        try {\n            assert v in [\"apt-android-7\", \"apt-android-5\"]\n        } catch (AssertionError e) {\n            throw new GradleException(\"Unsupported TERMUX_PACKAGE_VARIANT \\\"${v}\\\". Set it to apt-android-7 or apt-android-5, or unset it.\")\n        }\n    }\n}\ndownloadBootstraps.dependsOn checkPackageVariant","preventionTips":["Never export TERMUX_PACKAGE_VARIANT globally; set it per-build-command or per-CI-job so stale values cannot leak in.","If you rely on the default, explicitly `unset TERMUX_PACKAGE_VARIANT` at the top of CI scripts to neutralize inherited empty-string exports that bypass the Groovy Elvis fallback.","Keep the Gradle if/else chain, the Java PackageVariant enum, and the supported-values doc comment in app/build.gradle as a single atomic change unit — a drift between them is the most common source of this error during variant refactors.","Add a build-time assertion that runs before downloadBootstraps so an invalid variant fails with an actionable message instead of downloading the wrong archive.","Pin the supported-variant list in one place (a shared constant or generated file) and have both Gradle and Java reference it, eliminating manual sync."],"tags":["gradle","android","termux","build-config","environment-variables","configuration"],"backgroundTag":null,"analyzedSha":"3df69d1da197dd9bd71a3bafd902dffd720576b4","analyzedAt":"2026-08-13T22:46:28.294Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}