avajs/ava · error · Error

Conflicting configuration in ${fileForErrorMessage} and pack

Error message

Conflicting configuration in ${fileForErrorMessage} and package.json

What it means

AVA refuses to run with both a dedicated config file (ava.config.js/mjs/cjs, .avarc) and an `ava` key in package.json, since it cannot decide which wins — unless the file explicitly opts out (a factory config can accept package.json to allow merging). loadConfig throws this when a config file is found and packageConf still has keys.

Source

Thrown at lib/load-config.js:135

			if (jsonFile !== null) {
				unsupportedFiles.push(jsonFile);
			}

			[{config: fileConf, fileForErrorMessage, configFile} = {config: NO_SUCH_FILE, fileForErrorMessage: undefined}, ...conflicting] = results.filter(result => result !== null);

			searchDir = path.dirname(searchDir);
		} while (fileConf === NO_SUCH_FILE && searchDir !== stopAt);
	}

	if (conflicting.length > 0) {
		throw new Error(`Conflicting configuration in ${fileForErrorMessage} and ${conflicting.map(({fileForErrorMessage}) => fileForErrorMessage).join(' & ')}`);
	}

	if (fileConf !== NO_SUCH_FILE) {
		if (allowConflictWithPackageJson) {
			packageConf = {};
		} else if (Object.keys(packageConf).length > 0) {
			throw new Error(`Conflicting configuration in ${fileForErrorMessage} and package.json`);
		}

		if (!isPlainObject(fileConf) && typeof fileConf !== 'function') {
			throw new TypeError(`${fileForErrorMessage} must export a plain object or factory function`);
		}

		if (typeof fileConf === 'function') {
			fileConf = await fileConf({projectDir});

			if (!isPlainObject(fileConf)) {
				throw new TypeError(`Factory method exported by ${fileForErrorMessage} must return a plain object`);
			}
		}

		if ('ava' in fileConf) {
			throw new Error(`Encountered ’ava’ property in ${fileForErrorMessage}; avoid wrapping the configuration`);
		}
	}

View on GitHub (pinned to bbfd946322)

Solutions

  1. Delete the `ava` key from package.json, keeping the dedicated config file.
  2. Or delete the config file and keep only the package.json `ava` section.
  3. If using a config factory, merge intentionally: `export default ({projectDir}) => ({...packageJsonAvaOptions})`.
  4. Pass --config explicitly to select one file when multiple exist.

Example fix

// before
// package.json: {"ava": {"files": ["test/**/*.js"]}} and ava.config.js exists
// after: remove the "ava" key from package.json
$ node -e "delete require('./package.json').ava"
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const hasConfigFile = fs.existsSync('ava.config.js') || fs.existsSync('ava.config.mjs') || fs.existsSync('ava.config.cjs');
if (hasConfigFile && pkg.ava && Object.keys(pkg.ava).length > 0) {
  throw new Error('Remove the "ava" key from package.json or delete the config file');
}

Type guard

const hasNoConfigConflict = ({pkg, hasConfigFile}) => !(hasConfigFile && pkg?.ava && Object.keys(pkg.ava).length > 0);

Try / catch

try {
  await run();
} catch (err) {
  if (err.message.includes('and package.json')) {
    console.error('AVA found both a config file and an "ava" key in package.json — keep one');
    process.exitCode = 1;
  } else throw err;
}

Prevention

When it happens

Trigger: Having ava.config.js at the project root while package.json still contains an `"ava": {...}` section, then running AVA (with no explicit allowConflict setting).

Common situations: Migrating config from package.json to a standalone file but forgetting to delete the old `ava` block; scaffolding tools adding both; partial cleanup after an AVA version upgrade.

Related errors


AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02). Data as JSON: /api/errors/53afe5eb0569d03c. Report an issue: GitHub.