jest "TypeError: Cannot read properties of undefined (reading 'map')" only under --runInBand in CI
Debugs Jest "TypeError: Cannot read properties of undefined (reading 'map')" that only appears under --runInBand in CI. Explains how serial execution changes module state sharing versus parallel workers, and how to find the module-level state or mock that behaves differently in-band. Use when a test passes in parallel locally but fails in-band in CI. Not for the same error in all modes (a plain code bug), and not for mock mistakes that fail everywhere.
Look for module state that assumes parallel isolation. Under --runInBand every test file runs in one process, one after another - modules are loaded once and their top-level state persists across files. In parallel mode each worker gets a fresh module registry, so leaked state never collides. When in-band-only code hits "cannot read properties of undefined (reading 'map')", something earlier in the serial run left a module in a half-initialized state: a singleton configured by the first file that imported it, a mock applied globally that the later file does not expect, or an import-order dependency where file A must load before file B. Run the failing file alone in-band: if it passes alone, the polluter is another file running before it - bisect the file list to find it.
jest "TypeError: Cannot read properties of undefined (reading 'map')" only under --runInBand in CISteps
Run the failing test file completely alone with --runInBand. If it passes alone, another test file is polluting shared module state - the failure needs a partner to reproduce. Expected: you know whether the file fails solo (self-contained bug) or only with company (cross-file pollution).
If it needs company, bisect: run the failing file plus half the suite in-band, narrow down to the single file that triggers it. The polluter is usually a file that configures a shared module, sets a global mock, or imports modules in a surprising order. Expected: you have named the polluting file and the failing file as a pair.
Inspect what the polluter does at module scope: top-level singletons, global mock setups, environment variable changes, or imports with side effects. The undefined value in the error is a module export that the polluter replaced or never initialized. Expected: you found the shared state: a singleton, a global mock, or an import side effect.
Fix the sharing, not the symptom: reset modules between files (isolated module registries), move the side effect into proper setup/teardown, or make the singleton initialization idempotent. Expected: the pair passes together in-band and each still passes alone.
Run the whole suite in-band twice. Order-dependent state bugs are the flakiest kind - one green run is not proof. Expected: two consecutive full in-band runs are green.
Use this when
- "Cannot read properties of undefined" only under --runInBand
- tests passing in parallel but failing serially in CI
- module-level singletons or global mocks behaving differently in-band
Not for this skill when
- the same error in parallel and in-band (that is a straightforward code bug - the value really is undefined)
- mock setup errors that fail in every mode (fix the mock, not the execution mode)
Variant phrasings
jest runInBand fails parallel passes
The general form. The bisect-the-file-list technique is the core skill.
jest module state leak between test files
The mechanism phrasing. Same fix: isolate registries or clean up the side effect.
Why it happens
Jest parallel workers each get a fresh module registry, so module-level state (singletons, caches, configured clients) starts clean per worker. --runInBand runs everything in one process: the first file to import a module wins, and every later file sees whatever state the earlier files left behind. If an early file replaces a module export with a mock, or initializes a singleton halfway, a later file can find undefined where it expected an array - hence "reading 'map'" on undefined. CI often uses --runInBand on small runners to save memory, which is why the bug is CI-only.
Edge cases
- --runInBand used in CI to dodge worker memory limits: the memory problem is real, but in-band execution surfaces every hidden state dependency - budget time for this class of bug
- jest.resetModules as a band-aid: it works per file but slows the suite - prefer fixing the actual shared state
- the polluter is a setup file, not a test file: check setupFiles and globalSetup too, they run once per in-band process and their state persists
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_7rLNvLA0k6ZCdhx90g-S4g