jestjs/jest · error · Error
Custom export conditions specified but they are not an…
Error message
Custom export conditions specified but they are not an array of strings
What it means
Thrown by the JSDOM environment constructor when `testEnvironmentOptions.customExportConditions` is present but is not an array of strings. The validation checks `Array.isArray(...) && every(isString)`; if it fails, Jest cannot determine which package.json export conditions to use for module resolution.
Solutions
- Set `customExportConditions` to an array of strings: `['browser']`.
- If using docblock overrides, ensure valid JSON: `@jest-environment-options {"customExportConditions": ["browser"]}`.
- Remove the option entirely if you want the default (`['browser']` for jsdom).
Example fix
// before
module.exports = {
testEnvironment: 'jsdom',
testEnvironmentOptions: { customExportConditions: 'browser' },
};
// after
module.exports = {
testEnvironment: 'jsdom',
testEnvironmentOptions: { customExportConditions: ['browser'] },
}; Defensive patterns
Strategy: type-guard
Validate before calling
// Validate customExportConditions type in config
function validateExportConditions(opts) {
if ('customExportConditions' in opts) {
const c = opts.customExportConditions;
if (!Array.isArray(c) || !c.every(v => typeof v === 'string')) {
throw new TypeError('customExportConditions must be an array of strings');
}
}
} Type guard
function isStringArray(value: unknown): value is string[] {
return Array.isArray(value) && value.every(v => typeof v === 'string');
} Prevention
- Always pass customExportConditions as an array of strings.
- Use a JSON schema or config validation step in CI.
- When using docblock overrides, validate the JSON with a linter.
When it happens
Trigger: Setting `testEnvironmentOptions: { customExportConditions: 'browser' }` (string instead of array) or `{ customExportConditions: { browser: true } }` (object) or `{ customExportConditions: [123] }` (array with non-string elements) in jest.config.js or in a `@jest-environment-options` docblock.
Common situations: Confusing the type — writing a string or object instead of `['browser']`. Copy-pasting a config snippet from a blog that used the wrong type. Docblock override with malformed JSON.
Related errors
- Custom export conditions specified but they are not an…
- jest-haste-map: enableSymlinks config option was set, but…
- jest-haste-map: the `ignorePattern` option must be a RegExp
- Unable to forward JSDOM console output - neither sendTo nor…
- Attempted to display seed but seed value is undefined
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/9941f5d2146fca6d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/jest-environment-jsdom-abstract/src/index.ts:150
};
global.removeEventListener = function (
...args: Parameters<typeof originalRemoveListener>
) {
if (args[0] === 'error') {
userErrorListenerCount--;
}
return originalRemoveListener.apply(this, args);
};
if ('customExportConditions' in projectConfig.testEnvironmentOptions) {
const {customExportConditions} = projectConfig.testEnvironmentOptions;
if (
Array.isArray(customExportConditions) &&
customExportConditions.every(isString)
) {
this._configuredExportConditions = customExportConditions;
} else {
throw new Error(
'Custom export conditions specified but they are not an array of strings',
);
}
}
this.moduleMocker = new ModuleMocker(global);
this.fakeTimers = new LegacyFakeTimers({
config: projectConfig,
global,
moduleMocker: this.moduleMocker,
timerConfig: {
idToRef: (id: number) => id,
refToId: (ref: number) => ref,
},
});
this.fakeTimersModern = new ModernFakeTimers({View on GitHub (pinned to 8e6d128e4a)