{"record":{"id":"03eb8857e5b572b2","repo":"preactjs/preact","slug":"invalid-type-passed-to-createelement-array-is","errorCode":null,"errorMessage":"Invalid type passed to createElement(): ${Array.isArray(type) ? 'array' : type}","messagePattern":"Invalid type passed to createElement\\(\\): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"debug/src/debug.js","lineNumber":166,"sourceCode":"\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' &&\n\t\t\ttypeof vnode.ref != 'object' &&\n\t\t\t!('$$typeof' in vnode) // allow string refs when preact-compat is installed\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Component's \"ref\" property should be a function, or an object created ` +\n\t\t\t\t\t`by createRef(), but got [${typeof vnode.ref}] instead\\n` +\n\t\t\t\t\tserializeVNode(vnode) +\n\t\t\t\t\t`\\n\\n${getOwnerStack(vnode)}`\n\t\t\t);\n\t\t}","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/preactjs/preact/blob/e881e7e8386d7a430f87498a41c6a532992b4599/debug/src/debug.js#L148-L184","documentation":"Thrown from options._diff when vnode.type is a non-null object that does NOT carry the _children/_dom markers (so it is not a stray vnode), but is still invalid as a component type — e.g. a plain object, a Map, a Promise, or an array. Arrays are reported literally as 'array' for clarity. This is the catch-all for object types Preact cannot render.","triggerScenarios":"Passing a plain config object as a component: `<{} as any/>`; passing an array of components where one component was expected; passing a Promise (pre-Suspense) or a Map/Set as type; spreading a props object into the type position by mistake.","commonSituations":"Accidental destructuring swap: `const { type } = config; <type/>` where type is an object; HOC pipeline that returns a descriptor object instead of a component; migrating from a framework whose components are objects (e.g. Vue options objects) without wrapping; type-erased TypeScript where a discriminated union collapses to object.","solutions":["Inspect vnode.type at runtime: `console.log(typeof type, type)` — it must be a function, class, or string.","If the component is defined as an object literal, wrap it in a function: `const Comp = () => <obj {...props}/>`.","For arrays, map children instead: `<>{items.map(i => <Item key={i.id} />)}</>` rather than `<items/>`.","Check that imports resolve to a function/class — re-export issues can yield object module namespace records."],"exampleFix":"// before\nconst config = { label: 'Hi' };\nrender(<config />, root);\n\n// after\nfunction Config() {\n  return <div>{config.label}</div>;\n}\nrender(<Config />, root);","handlingStrategy":"type-guard","validationCode":"function assertValidVNodeType(type) {\n  if (type == null || typeof type === 'object') {\n    throw new Error(`Invalid vnode type: ${Array.isArray(type) ? 'array' : type}. Expected string|function|class.`);\n  }\n  return type;\n}\n\n// before constructing a vnode dynamically\nassertValidVNodeType(MyType);","typeGuard":"/** @param {unknown} t */\nfunction isValidPreactType(t) {\n  if (typeof t === 'string' || typeof t === 'function') return true;\n  // Allow null to skip rendering, disallow other objects\n  return t === null;\n}","tryCatchPattern":null,"preventionTips":["Always pass a function/class or string tag as the first arg to createElement/h.","Avoid spreading config objects into the type position.","Map arrays of data to arrays of elements; never use an array as a type."],"tags":["preact","createelement","vnode-type","object","debug-build"],"backgroundTag":null,"analyzedSha":"e881e7e8386d7a430f87498a41c6a532992b4599","analyzedAt":"2026-08-13T04:27:04.532Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}