apache/cordova-android · error · Error

Could not find apk architecture: ${arch} build-type: ${build

Error message

Could not find apk architecture: ${arch} build-type: ${buildResults.buildType}

What it means

findBestApkForArchitecture(buildResults, arch) filters buildResults.apkPaths by build type (names containing '-debug' for debug builds, otherwise non-debug names), then walks the list: a file whose name contains -x86/-arm must match '-'+arch, while a name with no arch suffix is treated as universal and returned immediately. Thrown when, after the build-type filter, no remaining APK matches the requested architecture.

Source

Thrown at lib/build.js:230

        const apkName = path.basename(p);
        if (buildResults.buildType === 'debug') {
            return /-debug/.exec(apkName);
        }
        return !/-debug/.exec(apkName);
    });
    const archPattern = new RegExp('-' + arch);
    const hasArchPattern = /-x86|-arm/;
    for (let i = 0; i < paths.length; ++i) {
        const apkName = path.basename(paths[i]);
        if (hasArchPattern.exec(apkName)) {
            if (archPattern.exec(apkName)) {
                return paths[i];
            }
        } else {
            return paths[i];
        }
    }
    throw new Error('Could not find apk architecture: ' + arch + ' build-type: ' + buildResults.buildType);
};

function PackageInfo (keystore, alias, storePassword, password, keystoreType) {
    const createNameKeyObject = (name, value) => ({ name, value: value.replace(/\\/g, '\\\\') });

    this.data = [
        createNameKeyObject('key.store', keystore),
        createNameKeyObject('key.alias', alias)
    ];

    if (storePassword) this.data.push(createNameKeyObject('key.store.password', storePassword));
    if (password) this.data.push(createNameKeyObject('key.alias.password', password));
    if (keystoreType) this.data.push(createNameKeyObject('key.store.type', keystoreType));
}

PackageInfo.prototype = {
    appendToProperties: function (propertiesParser) {
        for (const { name, value } of this.data) propertiesParser.set(name, value);

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Rebuild producing the needed ABI (or all ABIs) and verify the output filenames under platforms/android/app/build/outputs/apk/ contain '-<arch>' or no arch suffix.
  2. Inspect buildResults.apkPaths before deploying: confirm at least one basename matches the current buildType filter and the target arch.
  3. If you customize gradle output names, keep the standard '-debug'/'-release' and '-arm64-v8a'/'-x86'/'-x86_64' naming so the regex matching works.
  4. Remove stale outputs: `cordova clean android`, then rebuild.

Example fix

// before
const apk = build.findBestApkForArchitecture(buildResults, targetArch); // throws on ABI mismatch

// after: pre-check, and prefer an exact-ABI apk with universal fallback
const names = buildResults.apkPaths.map(p => path.basename(p));
const apk = buildResults.apkPaths.find(p => path.basename(p).includes('-' + targetArch)) ||
           buildResults.apkPaths.find(p => !/-x86|-arm/.test(path.basename(p)));
if (!apk) throw new Error('No ' + targetArch + ' APK in: ' + names.join(', '));
Defensive patterns

Strategy: validation

Validate before calling

const hasApkForArch = (buildResults, arch) =>
  buildResults.apkPaths.some(p =>
    new RegExp('-' + arch).test(path.basename(p)) || !/-x86|-arm/.test(path.basename(p))
  );

if (!hasApkForArch(buildResults, targetArch)) {
  throw new Error(`Rebuild for ${targetArch}: available APKs are ${buildResults.apkPaths.join(', ')}`);
}

Type guard

const isValidApkSet = (buildResults) =>
  Array.isArray(buildResults.apkPaths) &&
  buildResults.apkPaths.length > 0 &&
  typeof buildResults.buildType === 'string' && /debug|release/.test(buildResults.buildType);

Try / catch

try {
  apk = build.findBestApkForArchitecture(buildResults, targetArch);
} catch (e) {
  if (/Could not find apk architecture/.test(e.message)) {
    // recover by building the missing ABI, then retry once
    await androidApi.build({ ...opts, arch: [targetArch] });
    apk = build.findBestApkForArchitecture(buildResults, targetArch);
  } else throw e;
}

Prevention

When it happens

Trigger: The run/emulate flow detects the device arch via `Adb.shell(target, 'cat /proc/cpuinfo')` (/intel/ -> 'x86', else 'arm', lib/build.js:205-207) and calls this helper; it throws when the built APKs cover a different ABI, e.g. arch='x86' but only app-arm-debug.apk exists, or the '-debug' filter dropped every path because output names are nonstandard.

Common situations: Building with a single-ABI flag but deploying to the other ABI; stale apkPaths from a previous build after config changes; gradle output renaming (custom suffixes) breaking the -debug/-x86/-arm filename matching; build results containing no apks for the current buildType.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/d3b94250171d5429. Report an issue: GitHub.