Description
When endHydration() is called, if the cursor hasn't reached the end of siblings at any level, the SSR and client trees diverged. The developer gets no feedback about this — extra SSR nodes are silently left in the DOM.
Context
- In
packages/ui/src/hydrate/hydration-context.ts, endHydration() (lines 33-37) resets all state without checking if nodes were left unclaimed:
export function endHydration(): void {
isHydrating = false;
currentNode = null;
cursorStack.length = 0;
}
- If the SSR output has
<div><h1>Title</h1><p>Extra paragraph</p></div> but the client only claims <h1>, the <p> remains in the DOM unclaimed. This is correct behavior for tolerant mode (don't destroy extra content), but the developer should know their trees diverged.
- The cursor stack may also have entries if
enterChildren/exitChildren were unbalanced at end of hydration (separate from the empty-stack warning in exitChildren which fires mid-hydration).
- This should be
console.debug (not warn) since extra nodes from browser extensions are expected and normal.
Tasks
- Before resetting state in
endHydration(), check if currentNode !== null (unclaimed siblings remain).
- Check if
cursorStack.length > 0 (unbalanced enter/exit).
- Log appropriate dev-mode debug messages.
Files to modify
packages/ui/src/hydrate/hydration-context.ts — endHydration()
References
Acceptance Criteria
Progress
Description
When
endHydration()is called, if the cursor hasn't reached the end of siblings at any level, the SSR and client trees diverged. The developer gets no feedback about this — extra SSR nodes are silently left in the DOM.Context
packages/ui/src/hydrate/hydration-context.ts,endHydration()(lines 33-37) resets all state without checking if nodes were left unclaimed:<div><h1>Title</h1><p>Extra paragraph</p></div>but the client only claims<h1>, the<p>remains in the DOM unclaimed. This is correct behavior for tolerant mode (don't destroy extra content), but the developer should know their trees diverged.enterChildren/exitChildrenwere unbalanced at end of hydration (separate from the empty-stack warning inexitChildrenwhich fires mid-hydration).console.debug(notwarn) since extra nodes from browser extensions are expected and normal.Tasks
endHydration(), check ifcurrentNode !== null(unclaimed siblings remain).cursorStack.length > 0(unbalanced enter/exit).Files to modify
packages/ui/src/hydrate/hydration-context.ts—endHydration()References
plans/mutable-herding-journal.md(Claude plans)Acceptance Criteria
console.debugwith message like"[hydrate] Hydration ended with unclaimed nodes remaining. SSR tree may have extra content."console.debugwith stack depth infoProgress