{"record":{"id":"00f04f8ffba70fbf","repo":"facebook/react","slug":"536","errorCode":"536","errorMessage":"Cannot pass ref in renderToHTML because they will never be hydrated.","messagePattern":"Cannot pass ref in renderToHTML because they will never be hydrated\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-markup/src/ReactFizzConfigMarkup.js","lineNumber":124,"sourceCode":"  return parentContext;\n}\n\nexport function pushStartInstance(\n  target: Array<Chunk | PrecomputedChunk>,\n  type: string,\n  props: Object,\n  resumableState: ResumableState,\n  renderState: RenderState,\n  preambleState: null | PreambleState,\n  hoistableState: null | HoistableState,\n  formatContext: FormatContext,\n  textEmbedded: boolean,\n): ReactNodeList {\n  for (const propKey in props) {\n    if (hasOwnProperty.call(props, propKey)) {\n      const propValue = props[propKey];\n      if (propKey === 'ref' && propValue != null) {\n        throw new Error(\n          'Cannot pass ref in renderToHTML because they will never be hydrated.',\n        );\n      }\n      if (typeof propValue === 'function') {\n        throw new Error(\n          'Cannot pass event handlers (' +\n            propKey +\n            ') in renderToHTML because ' +\n            'the HTML will never be hydrated so they can never get called.',\n        );\n      }\n    }\n  }\n\n  return pushStartInstanceImpl(\n    target,\n    type,\n    props,","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-markup/src/ReactFizzConfigMarkup.js#L106-L142","documentation":"react-markup's experimental_renderToHTML produces plain HTML that is never hydrated, so a ref could never be attached; the markup Fizz host config (ReactFizzConfigMarkup) hard-throws at pushStart when any host element carries a non-null ref prop. The throw happens during rendering and rejects the renderToHTML promise via the destination's destroy path.","triggerScenarios":"Passing ref to any host element inside the tree given to experimental_renderToHTML - including refs added inside shared design-system components, inputs, or HOCs that unconditionally forward refs.","commonSituations":"Reusing client components or pages in a static-markup pipeline; component libraries whose inputs/buttons always attach refs; migrating from ReactDOMServer.renderToStaticMarkup to renderToHTML without removing refs.","solutions":["Remove ref from every element passed to renderToHTML.","In shared components, make the ref conditional (skip it when rendering static markup, e.g. behind an isStatic prop or a separate code path).","If you need element access, insert the returned HTML string client-side and use querySelector instead of a ref."],"exampleFix":"// before\nawait experimental_renderToHTML(<input ref={inputRef} />);\n\n// after\nconst html = await experimental_renderToHTML(<input />);\n// after inserting the HTML:\ncontainer.insertAdjacentHTML('beforeend', html);\ncontainer.querySelector('input').focus();","handlingStrategy":"validation","validationCode":"import {cloneElement, isValidElement} from 'react';\nfunction stripRefs(node) {\n  if (Array.isArray(node)) return node.map(stripRefs);\n  if (!isValidElement(node)) return node;\n  const {ref, ...props} = node.props; // eslint-disable-line no-unused-vars\n  if (props.children != null) props.children = stripRefs(props.children);\n  return cloneElement(node, {...props, ref: null});\n}\nconst html = await experimental_renderToHTML(stripRefs(<App />));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep refs out of any tree passed to renderToHTML - the output is never hydrated.","Make refs optional in shared components used by both client and static-markup pipelines.","Query the DOM after insertion instead of using refs on static HTML."],"tags":["ref","rendertohtml","react-markup","static-markup"],"backgroundTag":"ref-in-static-render","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}