Solving 'Detached from DOM' Errors in Cypress
Learn how to diagnose and fix 'Detached from DOM' errors in Cypress by eliminating stale element references and implementing proper re-querying strategies.
20 Jan 2026, 07:32 UTC

The Problem: Elements Vanishing During Interaction
A Detached from DOM error occurs when Cypress identifies a DOM element, but by the time it attempts to interact with it (clicking, typing, or asserting), the application has replaced that element with a new one. This is common in modern frameworks like React, Vue, or Angular where state updates trigger a re-render of the component tree.
The critical takeaway: Do not store elements in variables or aliases if the UI is volatile. You must re-query the DOM immediately before the action to ensure you are interacting with the current node.
Diagnostic Matrix
Use this table to identify the likely cause based on the behavior observed in the Cypress Command Log.
| Symptom | Likely Cause | Mechanism |
|---|---|---|
| Error occurs immediately after a network request | State-driven re-render | The API response triggered a UI update that swapped the element. |
| Error occurs during a transition/animation | Component swapping | A loading spinner disappeared and was replaced by the actual content. |
Error occurs when using .as('alias') |
Stale reference | The alias points to the memory address of the old node, not the new one. |
Step-by-Step Resolution
1. Identify the Stale Reference
Check your test code for patterns where an element is captured and then used later. This is the most frequent cause of detachment.
// ❌ RISKY: Storing the element in a variable
const submitBtn = cy.get('.submit-btn');
cy.wait(1000); // State change happens here
submitBtn.click(); // Error: Detached from DOM
2. Implement Re-Querying (The Primary Fix)
Chain your commands or call cy.get() again. Cypress's retryability works best when the query and the action are part of the same command chain.
// ✅ STABLE: Re-querying the element
cy.get('.submit-btn').click();
If you have complex logic between finding the element and clicking it, wrap the logic in a function or use cy.get() at the exact moment of interaction.
3. Guard Against Loading States
If the element is detached because a loading overlay is being removed, explicitly wait for the overlay to vanish before querying the target element.
// Ensure the loader is gone before interacting with the result
cy.get('.loading-spinner').should('not.exist');
cy.get('.result-item').first().click();
4. Adjust Command Timeouts
If the detachment happens because the transition between the "old" element and the "new" element is slow, increase the timeout for that specific command rather than the global config.
// Give the app 10 seconds to stabilize the DOM
cy.get('.dynamic-element', { timeout: 10000 }).should('be.visible').click();
Comparison: Aliases vs. Direct Queries
While aliases are useful for data, they can be dangerous for volatile DOM elements.
| Approach | Behavior | Risk Level |
|---|---|---|
cy.get('.el').as('myEl') |
Stores a reference to the element found at that moment. | High (if UI re-renders) |
cy.get('.el') |
Searches the current DOM every time it is called. | Low |
Verification and Limitations
To verify the fix, trigger the state change (e.g., a button click that fetches data) and observe the Cypress Command Log. You should see the GET command execute successfully immediately preceding the action, without a red "Detached from DOM" error appearing between them.
Limitations
- force: true: Using
{ force: true }in a click command may bypass the detachment error, but it does not fix the underlying race condition and can lead to "ghost clicks" where the action happens on an element that is no longer visible to the user. - cy.wait(number): Avoid hard-coded waits. They slow down the suite and do not guarantee the DOM has finished updating.
Rollback
Since these changes only affect the test script logic and not the application state or environment, rollback consists of reverting the git commit containing the modified .spec.js or .cy.js files.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.