apache/cordova-android · error · Error

Specified build config file does not exist: ${buildConfig}

Error message

Specified build config file does not exist: ${buildConfig}

What it means

build.js reads options.buildConfig (from the --buildConfig CLI flag or the programmatic options object) to supplement signing parameters, and first requires the file to exist on disk. Thrown by fs.existsSync failing before any JSON is parsed - the path itself resolves to nothing.

Source

Thrown at lib/build.js:84

        const gradleArgs = parseArgsStringToArgv(options.argv.gradleArg[0]);
        ret.extraArgs = ret.extraArgs.concat(gradleArgs);
    }

    const packageArgs = {};

    if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }

    ['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (flagName) {
        if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
    });

    const buildConfig = options.buildConfig;

    // If some values are not specified as command line arguments - use build config to supplement them.
    // Command line arguments have precedence over build config.
    if (buildConfig) {
        if (!fs.existsSync(buildConfig)) {
            throw new Error('Specified build config file does not exist: ' + buildConfig);
        }
        events.emit('log', 'Reading build config file: ' + path.resolve(buildConfig));
        const buildjson = fs.readFileSync(buildConfig, 'utf8');
        const config = JSON.parse(buildjson.replace(/^\ufeff/, '')); // Remove BOM
        if (config.android && config.android[ret.buildType]) {
            const androidInfo = config.android[ret.buildType];
            if (androidInfo.keystore && !packageArgs.keystore) {
                androidInfo.keystore = untildify(androidInfo.keystore);
                packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore);
                events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
            }

            ['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (key) {
                packageArgs[key] = packageArgs[key] || androidInfo[key];
            });
        }
    }

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Verify the path: `ls <path>`; if relative, re-run from the project root or pass an absolute path.
  2. If the file is missing, create a build.json with the android.debug/android.release keystore blocks.
  3. In CI, make sure the step that produces/copies build.json runs before cordova build.

Example fix

# before (run from platforms/android - relative path now points nowhere)
cordova build android --buildConfig=build.json

# after (absolute path from the project root)
cordova build android --buildConfig="$(pwd)/build.json"
Defensive patterns

Strategy: validation

Validate before calling

const buildConfigPath = path.resolve(options.buildConfig);
if (!fs.existsSync(buildConfigPath)) {
  throw new Error(`buildConfig not found: ${buildConfigPath} - create it or fix the path`);
}
// safe to pass on
await androidApi.build({ ...options, buildConfig: buildConfigPath });

Try / catch

try {
  await androidApi.build(opts);
} catch (e) {
  if (/build config file does not exist/.test(e.message)) {
    throw new Error(`Missing ${opts.buildConfig} - run from the project root or pass an absolute path`);
  }
  throw e;
}

Prevention

When it happens

Trigger: `cordova build/run/emulate android --buildConfig=<path>` (or Api.build({ buildConfig: '<path>' })) where <path> does not exist - wrong filename, wrong directory, or a relative path resolved against an unexpected cwd.

Common situations: Running the CLI from a different working directory with a relative --buildConfig path; typo'd filename; build.json not committed/present in CI; file moved after docs were written.

Related errors


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