Bug: clearContainerSparingly throws "reading 'toLowerCase'" when a <link>'s rel is not a string

Đang mở Phù hợp với người mới
#37,747 4 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@abin222 đang làm issue này rồi.

Từ ngày 3/10/2026.

  • #37750 của @abin222 — đang mở
  • #37769 của @Irish-Joseph — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
74/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
javascript, react
Lĩnh vực
frontend

Hướng nghiên cứu

Bắt đầu với các branch clearContainerSparingly và clearHydrationBoundary được hiển thị trong issue, sau đó chạy bản tái hiện HTML được cung cấp với một link rel không phải là chuỗi. Được xem là hoàn tất khi việc xóa và render phía client không còn bị dừng với một toLowerCase TypeError khi rel không phải là chuỗi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

React version: 19.3.0 (also 19.2.x as vendored by Next.js 16.3.4)

Steps To Reproduce

  1. Server-render a full document and hydrate it with hydrateRoot(document, …), where <body>'s first element is a <div>.
  2. Before hydration, something prepends another <div> to <body> (browser extensions and crawlers do this). React pairs it with the expected <div>, the root fails to hydrate (#418) and React clears the container to client-render.
  3. <head> contains a <link> whose rel property is not a string. We hit this in production from a crawler built on a non-standard DOM (the Obscura headless browser: html5ever DOM + V8 via deno_core).

Link to code example — minimal, React only (save as .html, open in Chrome):

<!DOCTYPE html><html><head><link rel="icon" href="data:,"></head><body><div><p>hello</p></div><script type="module">
import { createElement as h } from 'https://esm.sh/[email protected]';
import { hydrateRoot } from 'https://esm.sh/[email protected]/client';

function App() {
  return h('html', null,
    h('head', null, h('link', { rel: 'icon', href: 'data:,' })),
    h('body', null, h('div', null, h('p', null, 'hello'))));
}

document.body.prepend(document.createElement('div'));           // 2.
const link = document.createElement('link');
Object.defineProperty(link, 'rel', { get: () => undefined });   // 3. simulates the non-standard DOM
document.head.appendChild(link);

hydrateRoot(document, h(App));
</script></body></html>

Without the defineProperty line, React only reports the recoverable #418 and recovers. With it, the client render aborts.

The current behavior

Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase') from clearContainerSparingly:

case "LINK":
  if ("stylesheet" === node.rel.toLowerCase()) continue;

The same unguarded access exists in the "head" branch of clearHydrationBoundary:

("LINK" === nodeName && "stylesheet" === node.rel.toLowerCase()) ||

The page is left as server HTML with no event handlers attached.

The expected behavior

Clearing the container should not assume rel is a string — e.g. typeof node.rel === "string" && … (what we patched locally), or reading node.getAttribute("rel") case-insensitively.

Ngôn ngữ chính
JavaScript
Star
252k
Fork
51.7k
Merge trung bình
1 ngày 2 giờ
Pull request đã merge (30 ngày)
40

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của react/react

Tất cả issue của react/react

Issue tương tự

Thêm issue về JavaScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.