cypress "Cannot read properties of null (reading 'setAttribute')" only in headless CI runs
Fixes the 'Cannot read properties of null (reading setAttribute)' TypeError that appears only in headless Cypress CI runs. Shows how to trace the null element from the stack, wait for the element before acting on it, and add a guard so the code fails loudly instead of crashing. Use when app code touches a DOM element that is null under headless timing. Not for selector problems in Cypress commands, API failures, or errors that also happen headed.
TL;DR
Somewhere your app code calls setAttribute on an element lookup that returned null, and it only happens headless because headless timing shifts when the element appears. Find the line from the stack trace, wait for the element to exist before the code touches it (or guard the lookup and throw a clear error), and the TypeError disappears. Do not just retry the test until it passes.
cypress "Cannot read properties of null (reading 'setAttribute')" only in headless CI runsSteps
- Open the CI failure and copy the stack trace. Find the first frame in your own code (not in Cypress internals) that calls
setAttribute. Expected: you have the file and line where the null element is used. - Read the lookup just above it (a querySelector, getElementById, or framework ref). Ask why it can return null at that moment: the element renders after an async fetch, after a route change, or after a conditional branch. Expected: you can name the race.
- Make the code wait for the element instead of assuming it: await the data or the render condition before touching the DOM, or move the
setAttributecall into the callback that creates the element. Expected: the lookup cannot run before the element exists. - As a backstop, guard the lookup so a future miss throws your own clear error naming the element instead of the cryptic null TypeError. Expected: any regression fails with a message you can act on.
- Rerun the spec headless several times in CI. Expected: no TypeError across the runs.
Use this when
- App code throws "reading 'setAttribute'" on null only in headless CI
- The stack trace points at your code, not at a Cypress command
- The same spec passes headed or locally
Not for this skill when
- A Cypress command itself cannot find the element (fix the selector or the wait)
- The error happens headed too (plain bug, not a headless timing issue)
- The null comes from an API response, not the DOM (that is a data problem)
Variant phrasings
- cypress setAttribute of null headless only
- cannot read properties of null in cypress CI
- cypress headless timing element null error
Why it happens
Headless Chrome runs on a different timing profile than headed: rendering, font loading, and animation frames interleave differently, so an element your code expects synchronously may not be in the DOM yet. Locally the timing usually lines up by luck. The null is not a Cypress bug; it is app code racing the render.
Edge cases
- If the element only exists on some routes, the guard should handle "element legitimately absent" as a separate case from "element not yet rendered".
- Framework refs (React ref, Vue ref) can be null during the same window; the same wait-then-touch ordering applies.
- If you cannot reproduce headless locally, run the single spec with the CI viewport size; small viewports change what renders and when.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstPEu8e3XToeA8smtxTIjCA