avajs/ava · error · Error

Conflicting configuration in ${fileForErrorMessage} and ${co

Error message

Conflicting configuration in ${fileForErrorMessage} and ${conflicting.map(({fileForErrorMessage}) => fileForErrorMessage).join(' & ')}

What it means

When AVA searches upward from the project directory it may find multiple config files (ava.config.js, .avarc, etc.). If more than one config file is found in different searched directories, loadConfig throws to avoid ambiguous, conflicting configuration.

Source

Thrown at lib/load-config.js:128

		do {
			const [jsonFile, ...results] = await Promise.all([ // eslint-disable-line no-await-in-loop
				checkJsonFile(searchDir),
				loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.js')}),
				loadConfigFile({projectDir, configFile: path.join(searchDir, 'ava.config.mjs')}),
			]);

			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`);

View on GitHub (pinned to bbfd946322)

Solutions

  1. Delete or rename the older/extra config file, keeping exactly one.
  2. Consolidate all AVA options into the single top-level config file.
  3. Search the repo for ava.config.*, .avarc, and package.json 'ava' keys and remove strays.
  4. Run AVA from the directory whose config you intend to use.

Example fix

// before: repo root has ava.config.js AND packages/app/ava.config.mjs
// after: delete packages/app/ava.config.mjs, keep ava.config.js at root
$ git rm packages/app/ava.config.mjs
Defensive patterns

Strategy: validation

Validate before calling

import {globbySync} from 'globby';
const found = globbySync(['ava.config.{js,mjs,cjs}', '.avarc', 'ava.config.json'], {gitignore: false});
if (found.length > 1) throw new Error(`Multiple AVA configs found: ${found.join(', ')}`);

Type guard

const hasSingleConfig = files => files.length === 1;

Try / catch

try {
  await run();
} catch (err) {
  if (err.message.startsWith('Conflicting configuration in')) {
    console.error('Keep exactly one AVA config file in the project');
    process.exitCode = 1;
  } else throw err;
}

Prevention

When it happens

Trigger: Having both ava.config.js in the repo root and an ava.config.mjs/.avarc in a subdirectory from which AVA resolves config, so the upward search discovers several files that each define configuration.

Common situations: Leftover config file from a previous AVA version or tool rename; monorepo where a nested package kept its own ava config; duplicated config after copy-pasting a project.

Related errors


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