{"record":{"id":"f94b80f481f818d0","repo":"facebook/react","slug":"61","errorCode":"61","errorMessage":"`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://react.dev/link/dangerously-set-inner-html for more information.","messagePattern":"`props\\.dangerouslySetInnerHTML` must be in the form `(.+?)`\\. Please visit https://react\\.dev/link/dangerously-set-inner-html for more information\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-dom-bindings/src/client/ReactDOMComponent.js","lineNumber":653,"sourceCode":"      return;\n    }\n    case 'onScrollEnd': {\n      if (value != null) {\n        if (__DEV__ && typeof value !== 'function') {\n          warnForInvalidEventListener(key, value);\n        }\n        listenToNonDelegatedEvent('scrollend', domElement);\n        if (enableScrollEndPolyfill) {\n          // For use by the polyfill.\n          listenToNonDelegatedEvent('scroll', domElement);\n        }\n      }\n      return;\n    }\n    case 'dangerouslySetInnerHTML': {\n      if (value != null) {\n        if (typeof value !== 'object' || !('__html' in value)) {\n          throw new Error(\n            '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +\n              'Please visit https://react.dev/link/dangerously-set-inner-html ' +\n              'for more information.',\n          );\n        }\n        const nextHtml: any = value.__html;\n        if (nextHtml != null) {\n          if (props.children != null) {\n            throw new Error(\n              'Can only set one of `children` or `props.dangerouslySetInnerHTML`.',\n            );\n          }\n          const lastHtml: any =\n            prevValue != null ? (prevValue as any).__html : undefined;\n          if (lastHtml !== nextHtml) {\n            domElement.innerHTML = nextHtml;\n          }\n        }","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-dom-bindings/src/client/ReactDOMComponent.js#L635-L671","documentation":"dangerouslySetInnerHTML must be an object of the exact shape {__html: string}. During prop application on standard host elements (setProp), React checks `typeof value !== 'object' || !('__html' in value)` and throws when the shape is wrong. This guards the only sanctioned raw-HTML injection API, whose misuse is a classic XSS vector.","triggerScenarios":"Writing dangerouslySetInnerHTML=\"<b>hi</b>\" (string), {{html: ...}} (missing double underscores), {{__html: ..., other: 1}} is fine shape-wise but typos like {{_html:}} or {{innerHTML:}} throw; also spreading props where dangerouslySetInnerHTML came from JSON data.","commonSituations":"Converting innerHTML assignments to React; copy-pasting docs with mangled underscores; data-driven rendering where the field is sometimes a plain string; markdown renderers misconfigured.","solutions":["Use the exact shape: dangerouslySetInnerHTML={{__html: htmlString}}","Sanitize the string with DOMPurify before injecting: dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(html)}}","If the data arrives as a string field, wrap it at the call site instead of renaming keys downstream","Prefer real JSX children or a markdown component when possible"],"exampleFix":"// before\n<div dangerouslySetInnerHTML=\"<b>bold</b>\"></div>\n<div dangerouslySetInnerHTML={{html: '<b>bold</b>'}}></div>\n\n// after\n<div dangerouslySetInnerHTML={{__html: '<b>bold</b>'}}></div>","handlingStrategy":"type-guard","validationCode":"function toDangerousHtml(value: unknown): {__html: string} | undefined {\n  if (value == null) return undefined;\n  if (typeof value === 'object' && '__html' in value) return value as {__html: string};\n  if (typeof value === 'string') return {__html: DOMPurify.sanitize(value)};\n  throw new TypeError('dangerouslySetInnerHTML must be {__html: string} or a string to wrap');\n}","typeGuard":"const hasHtmlShape = (v: unknown): v is {__html: string} =>\n  typeof v === 'object' && v !== null && '__html' in v;","tryCatchPattern":"Catch at the data edge, not in render: normalize any html field with toDangerousHtml() in a useMemo before passing props.","preventionTips":["Centralize every dangerouslySetInnerHTML usage behind one sanitized helper","DOMPurify.sanitize everything before it reaches __html","Add a unit test asserting the helper always returns {__html: string}"],"tags":["react-dom","dangerouslysetinnerhtml","props-validation","xss"],"backgroundTag":"dangerouslysetinnerhtml-invalid-shape","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}