{"record":{"id":"ca6327507e3b1132","repo":"termux/termux-app","slug":"unsupported-termux-app-package-variant-s","errorCode":null,"errorMessage":"Unsupported TERMUX_APP_PACKAGE_VARIANT \"%s\"","messagePattern":"Unsupported TERMUX_APP_PACKAGE_VARIANT \"(.+?)\"","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"termux-shared/src/main/java/com/termux/shared/termux/TermuxBootstrap.java","lineNumber":30,"sourceCode":"\n    private static final String LOG_TAG = \"TermuxBootstrap\";\n\n    /** The field name used by Termux app to store package variant in\n     * {@link TERMUX_APP#BUILD_CONFIG_CLASS_NAME} class. */\n    public static final String BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT = \"TERMUX_PACKAGE_VARIANT\";\n\n\n    /** The {@link PackageManager} for the bootstrap in the app APK added in app/build.gradle. */\n    public static PackageManager TERMUX_APP_PACKAGE_MANAGER;\n\n    /** The {@link PackageVariant} for the bootstrap in the app APK added in app/build.gradle. */\n    public static PackageVariant TERMUX_APP_PACKAGE_VARIANT;\n\n    /** Set {@link #TERMUX_APP_PACKAGE_VARIANT} and {@link #TERMUX_APP_PACKAGE_MANAGER} from {@code packageVariantName} passed. */\n    public static void setTermuxPackageManagerAndVariant(@Nullable String packageVariantName) {\n        TERMUX_APP_PACKAGE_VARIANT = PackageVariant.variantOf(packageVariantName);\n        if (TERMUX_APP_PACKAGE_VARIANT == null) {\n            throw new RuntimeException(\"Unsupported TERMUX_APP_PACKAGE_VARIANT \\\"\" + packageVariantName + \"\\\"\");\n        }\n\n        Logger.logVerbose(LOG_TAG, \"Set TERMUX_APP_PACKAGE_VARIANT to \\\"\" + TERMUX_APP_PACKAGE_VARIANT + \"\\\"\");\n\n        // Set packageManagerName to substring before first dash \"-\" in packageVariantName\n        int index = packageVariantName.indexOf('-');\n        String packageManagerName = (index == -1) ? null : packageVariantName.substring(0, index);\n        TERMUX_APP_PACKAGE_MANAGER = PackageManager.managerOf(packageManagerName);\n        if (TERMUX_APP_PACKAGE_MANAGER == null) {\n            throw new RuntimeException(\"Unsupported TERMUX_APP_PACKAGE_MANAGER \\\"\" + packageManagerName + \"\\\" with variant \\\"\" + packageVariantName + \"\\\"\");\n        }\n\n        Logger.logVerbose(LOG_TAG, \"Set TERMUX_APP_PACKAGE_MANAGER to \\\"\" + TERMUX_APP_PACKAGE_MANAGER + \"\\\"\");\n    }\n\n    /**\n     * Set {@link #TERMUX_APP_PACKAGE_VARIANT} and {@link #TERMUX_APP_PACKAGE_MANAGER} with the\n     * {@link #BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT} field value from the","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/termux/termux-app/blob/3df69d1da197dd9bd71a3bafd902dffd720576b4/termux-shared/src/main/java/com/termux/shared/termux/TermuxBootstrap.java#L12-L48","documentation":"Thrown by TermuxBootstrap.setTermuxPackageManagerAndVariant when packageVariantName does not match any PackageVariant enum value. Valid variants are 'apt-android-7' and 'apt-android-5'. variantOf() does a case-sensitive equality check against the enum names; any other string (including null passed safely returns null before this, but an unrecognized non-empty string) triggers the exception.","triggerScenarios":"TERMUX_PACKAGE_VARIANT build config field is set to an unsupported value (e.g. 'apt-android-6', 'tapm-android-7', 'APT-ANDROID-7' with wrong case, or a typo); a plugin reads a stale/wrong build config field from the Termux app; the variant string has trailing whitespace.","commonSituations":"Custom build sets an unregistered variant in build.gradle; upgrading introduced a new variant name not yet in the enum; sharedUserId plugin reads a field that does not exist, returning garbage.","solutions":["Set TERMUX_PACKAGE_VARIANT in build.gradle to one of the supported values: 'apt-android-7' or 'apt-android-5'.","Trim and lower-case the variant string before lookup if whitespace/case is suspected.","Ensure the build config field name matches BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT exactly.","If you forked and added a variant, also add it to the PackageVariant enum."],"exampleFix":"// before\npublic static PackageVariant variantOf(String name) {\n    if (name == null || name.isEmpty()) return null;\n    for (PackageVariant v : PackageVariant.values()) {\n        if (v.name.equals(name)) return v;\n    }\n    return null;\n}\n\n// after (case-insensitive + trimmed lookup with explicit error listing valid values)\npublic static PackageVariant variantOf(String name) {\n    if (name == null) return null;\n    String key = name.trim();\n    if (key.isEmpty()) return null;\n    for (PackageVariant v : PackageVariant.values()) {\n        if (v.name.equalsIgnoreCase(key)) return v;\n    }\n    throw new IllegalArgumentException(\"Unknown package variant '\" + name + \"'. Valid: apt-android-7, apt-android-5\");\n}","handlingStrategy":"validation","validationCode":"String v = (packageVariantName == null) ? null : packageVariantName.trim();\nif (v == null || PackageVariant.variantOf(v) == null) {\n    throw new IllegalArgumentException(\n        \"Unsupported variant: \" + v + \". Valid: apt-android-7, apt-android-5\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    TermuxBootstrap.setTermuxPackageManagerAndVariant(variant);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported TERMUX_APP_PACKAGE_VARIANT\")) {\n        // fallback to default variant or fail build\n        throw new BuildException(e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Set TERMUX_PACKAGE_VARIANT in build.gradle to a registered enum value.","Trim and validate the variant string before lookup.","Keep the PackageVariant enum in sync with the build variants you ship."],"tags":["bootstrap","build-config","enum","configuration","termux"],"backgroundTag":null,"analyzedSha":"3df69d1da197dd9bd71a3bafd902dffd720576b4","analyzedAt":"2026-08-13T22:46:28.294Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}