{"record":{"id":"9f6c1b7f13657b02","repo":"preactjs/preact","slug":"invalid-type-passed-to-createelement-type-d","errorCode":null,"errorMessage":"Invalid type passed to createElement(): ${type}\n\nDid you accidentally pass a JSX literal as JSX twice?\n\n  let My${getDisplayName(vnode)} = ${serializeVNode(type)};\n  let vnode = <My${getDisplayName(vnode)} />;\n\nThis usually happens when you export a JSX literal and not the component.\n\n${getOwnerStack(vnode)}","messagePattern":"Invalid type passed to createElement\\(\\): (.+?)\n\nDid you accidentally pass a JSX literal as JSX twice\\?\n\n  let My(.+?) = (.+?);\n  let vnode = <My(.+?) />;\n\nThis usually happens when you export a JSX literal and not the component\\.\n\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"debug/src/debug.js","lineNumber":156,"sourceCode":"\n\t\tif (oldRoot) oldRoot(vnode, parentNode);\n\t};\n\n\toptions._diff = vnode => {\n\t\tlet { type } = vnode;\n\n\t\thooksAllowed = true;\n\n\t\tif (type === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'Undefined component passed to createElement()\\n\\n' +\n\t\t\t\t\t'You likely forgot to export your component or might have mixed up default and named imports' +\n\t\t\t\t\tserializeVNode(vnode) +\n\t\t\t\t\t`\\n\\n${getOwnerStack(vnode)}`\n\t\t\t);\n\t\t} else if (type != null && typeof type == 'object') {\n\t\t\tif (type._children !== undefined && type._dom !== undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid type passed to createElement(): ${type}\\n\\n` +\n\t\t\t\t\t\t'Did you accidentally pass a JSX literal as JSX twice?\\n\\n' +\n\t\t\t\t\t\t`  let My${getDisplayName(vnode)} = ${serializeVNode(type)};\\n` +\n\t\t\t\t\t\t`  let vnode = <My${getDisplayName(vnode)} />;\\n\\n` +\n\t\t\t\t\t\t'This usually happens when you export a JSX literal and not the component.' +\n\t\t\t\t\t\t`\\n\\n${getOwnerStack(vnode)}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new Error(\n\t\t\t\t'Invalid type passed to createElement(): ' +\n\t\t\t\t\t(Array.isArray(type) ? 'array' : type)\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\tvnode.ref !== undefined &&\n\t\t\ttypeof vnode.ref != 'function' &&","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/preactjs/preact/blob/e881e7e8386d7a430f87498a41c6a532992b4599/debug/src/debug.js#L138-L174","documentation":"Thrown from options._diff when vnode.type is a non-null object that looks like an already-created vnode (it has both _children and _dom properties). This signals a JSX literal was used where a component was expected — i.e. an element was passed into createElement as the type rather than as children. The diagnostic message even sketches the mistaken pattern (`let MyX = <X/>; let vnode = <MyX/>`).","triggerScenarios":"Exporting a JSX element instead of a component: `export const Header = <h1/>` then using `<Header/>`; storing the result of `h()` or a JSX expression and then rendering it as a component type; double-wrapping JSX: `const Wrapper = <Comp/>; <Wrapper/>`; spreading an element into createElement's first arg.","commonSituations":"Refactor that turned a component into a configured element for convenience (e.g. `export const Button = <Button variant='primary'/>`); HOC that mistakenly returns an element rather than a component; copying a pattern from a config file where a default element was exported; passing preact-render-to-string output back into render.","solutions":["Find the export that is an element and convert it to a component: `export function Header() { return <h1/>; }` instead of `export const Header = <h1/>`.","If you need a pre-configured element, wrap it: `export const Header = () => <h1 className='x'/>`.","Trace the import chain back to the definition and confirm `typeof Definition === 'function'`.","Search the codebase for `= <` assignments in exported constants — these are the likely culprits."],"exampleFix":"// before\nexport const Card = <div className='card' />;\n// consumer\nimport { Card } from './Card';\nrender(<Card />, root);\n\n// after\nexport function Card() {\n  return <div className='card' />;\n}\nrender(<Card />, root);","handlingStrategy":"type-guard","validationCode":"function assertComponentNotElement(component, name) {\n  if (component && typeof component === 'object' && '_children' in component && '_dom' in component) {\n    throw new Error(`\"${name}\" is a JSX element, not a component. Wrap it: function C(){ return element; }`);\n  }\n  if (typeof component !== 'function') {\n    throw new Error(`\"${name}\" is not a renderable component (typeof ${typeof component}).`);\n  }\n  return component;\n}\n\nimport { Card } from './Card';\nassertComponentNotElement(Card, 'Card');","typeGuard":"/** @param {unknown} c */\nfunction isVNodeLike(c) {\n  return c != null && typeof c === 'object' && '_children' in c && '_dom' in c;\n}\n/** @param {unknown} c */\nfunction isComponent(c) {\n  return typeof c === 'function' || typeof c === 'string';\n}","tryCatchPattern":null,"preventionTips":["Never export a JSX literal — always export a component function or class.","Search the codebase for `export const X = <` patterns during review.","When wrapping a pre-configured element, return it from a function component."],"tags":["preact","createelement","jsx","vnode","debug-build"],"backgroundTag":null,"analyzedSha":"e881e7e8386d7a430f87498a41c6a532992b4599","analyzedAt":"2026-08-13T04:27:04.532Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}