{"record":{"id":"a799a39b96013dc7","repo":"avajs/ava","slug":"fileforerrormessage-must-export-a-plain-object","errorCode":null,"errorMessage":"${fileForErrorMessage} must export a plain object or factory function","messagePattern":"(.+?) must export a plain object or factory function","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/load-config.js","lineNumber":139,"sourceCode":"\t\t\t[{config: fileConf, fileForErrorMessage, configFile} = {config: NO_SUCH_FILE, fileForErrorMessage: undefined}, ...conflicting] = results.filter(result => result !== null);\n\n\t\t\tsearchDir = path.dirname(searchDir);\n\t\t} while (fileConf === NO_SUCH_FILE && searchDir !== stopAt);\n\t}\n\n\tif (conflicting.length > 0) {\n\t\tthrow new Error(`Conflicting configuration in ${fileForErrorMessage} and ${conflicting.map(({fileForErrorMessage}) => fileForErrorMessage).join(' & ')}`);\n\t}\n\n\tif (fileConf !== NO_SUCH_FILE) {\n\t\tif (allowConflictWithPackageJson) {\n\t\t\tpackageConf = {};\n\t\t} else if (Object.keys(packageConf).length > 0) {\n\t\t\tthrow new Error(`Conflicting configuration in ${fileForErrorMessage} and package.json`);\n\t\t}\n\n\t\tif (!isPlainObject(fileConf) && typeof fileConf !== 'function') {\n\t\t\tthrow new TypeError(`${fileForErrorMessage} must export a plain object or factory function`);\n\t\t}\n\n\t\tif (typeof fileConf === 'function') {\n\t\t\tfileConf = await fileConf({projectDir});\n\n\t\t\tif (!isPlainObject(fileConf)) {\n\t\t\t\tthrow new TypeError(`Factory method exported by ${fileForErrorMessage} must return a plain object`);\n\t\t\t}\n\t\t}\n\n\t\tif ('ava' in fileConf) {\n\t\t\tthrow new Error(`Encountered ’ava’ property in ${fileForErrorMessage}; avoid wrapping the configuration`);\n\t\t}\n\t}\n\n\tconst config = {\n\t\t...defaults, nonSemVerExperiments: {}, ...fileConf, ...packageConf, projectDir, configFile,\n\t};","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/load-config.js#L121-L157","documentation":"The default export of an AVA config file must be either a plain object of options or a factory function returning such an object (optionally async, receiving {projectDir}). If it is anything else — a class, array, string, number, etc. — loadConfig throws this TypeError.","triggerScenarios":"Exporting an array, class instance, or primitive: `export default ['test/**/*.js']` or `export default 'config'`; exporting a non-plain object built with Object.create(null) via unusual constructors.","commonSituations":"Copy-paste mistakes where the config value was meant to be nested inside an object; default export accidentally set to an import of something else; TypeScript transpilation emitting unexpected wrappers.","solutions":["Wrap the configuration in a plain object: `export default {files: [...]}`.","If exporting an array's contents, spread them: `export default {...options}`.","Ensure the default export is a function only if it returns a plain object (async allowed).","Verify the transpiler/bundler output preserves a plain-object default export."],"exampleFix":"// before\nexport default ['test/**/*.js'];\n// after\nexport default {files: ['test/**/*.js']};","handlingStrategy":"type-guard","validationCode":"const mod = await import(configPath);\nconst c = mod.default;\nconst isPlainObject = v => v !== null && typeof v === 'object' && !Array.isArray(v) && (v.constructor === Object || v.constructor === undefined);\nif (!isPlainObject(c) && typeof c !== 'function') {\n  throw new TypeError(`${configPath} must default-export a plain object or factory function`);\n}","typeGuard":"const isValidAvaConfig = v => (v !== null && typeof v === 'object' && !Array.isArray(v)) || typeof v === 'function';","tryCatchPattern":"try {\n  await run();\n} catch (err) {\n  if (err.message.includes('must export a plain object or factory function')) {\n    console.error('Default export must be a plain object or a (possibly async) factory returning one');\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Default-export an object literal, not arrays, primitives, or class instances.","Verify factory configs return plain objects on every path, including async.","Check transpiler output preserves the plain-object default export.","Add a config self-test that imports the config file in CI."],"tags":["configuration","type-error","validation","default-export"],"backgroundTag":"schema-validation-failed","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}