{"record":{"id":"4ca47a6f9bbd220f","repo":"pmndrs/react-three-fiber","slug":"r3f-name-is-not-part-of-the-three-namespace-d","errorCode":null,"errorMessage":"R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively","messagePattern":"R3F: (.+?) is not part of the THREE namespace! Did you forget to extend\\? See: https://docs\\.pmnd\\.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/fiber/src/core/reconciler.tsx","lineNumber":179,"sourceCode":"  objects: T,\n): React.ExoticComponent<ThreeElement<any>> | void {\n  if (isConstructor(objects)) {\n    const Component = `${i++}`\n    catalogue[Component] = objects\n    return Component as any\n  } else {\n    Object.assign(catalogue, objects)\n  }\n}\n\nfunction validateInstance(type: string, props: HostConfig['props']): void {\n  // Get target from catalogue\n  const name = toPascalCase(type)\n  const target = catalogue[name]\n\n  // Validate element target\n  if (type !== 'primitive' && !target)\n    throw new Error(\n      `R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`,\n    )\n\n  // Validate primitives\n  if (type === 'primitive' && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`)\n\n  // Throw if an object or literal was passed for args\n  if (props.args !== undefined && !Array.isArray(props.args)) throw new Error('R3F: The args prop must be an array!')\n}\n\nfunction createInstance(type: string, props: HostConfig['props'], root: RootStore): HostConfig['instance'] {\n  // Remove three* prefix from elements if native element not present\n  type = toPascalCase(type) in catalogue ? type : type.replace(PREFIX_REGEX, '')\n\n  validateInstance(type, props)\n\n  // Regenerate the R3F instance for primitives to simulate a new object\n  if (type === 'primitive' && props.object?.__r3f) delete props.object.__r3f","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/pmndrs/react-three-fiber/blob/ff3899dbf43d2a88895fecf53c147192abfd7431/packages/fiber/src/core/reconciler.tsx#L161-L197","documentation":"react-three-fiber resolves JSX element names (e.g. <orbitControls>, <mesh>) by looking up the PascalCase name in a catalogue of THREE.* classes. If the name isn't a member of the THREE namespace (or hasn't been registered), the reconciler throws this validation error during createInstance/commitUpdate instead of rendering 'undefined' elements. Third-party objects must be registered explicitly because they don't ship inside the THREE namespace.","triggerScenarios":"Using a JSX tag whose PascalCase name is not in the catalogue: typos like <meesh>, third-party/derived classes used without calling extend({ OrbitControls }), tree-shaken/custom builds where the class isn't imported from 'three', or namespaced usage like <threeMesh> when the underlying THREE.Mesh is not exported by the installed three version.","commonSituations":"Upgrading three.js or R3F versions where an addon moved from examples/jsm to a different path; using controls/postprocessing from three-stdlib or drei imports without extend(); a typo'd element name; bundler tree-shaking removing a class that was never explicitly imported; JSX intrinsic types present but runtime registration missing.","solutions":["If it's a typo, correct the tag name so its PascalCase form matches a THREE export (e.g. mesh -> THREE.Mesh).","For third-party or addon objects, register them: extend({ OrbitControls }) (and import OrbitControls from 'three/examples/jsm/controls/OrbitControls.js' or 'three-stdlib') before using <orbitControls />.","Make sure the class is actually imported so it's included in the bundle — add an explicit import even if only used in extend().","After upgrading three/R3F, re-check the addon import path and re-run extend() with the new exports."],"exampleFix":"// before\nimport { Canvas } from '@react-three/fiber'\n<Canvas><orbitControls /></Canvas> // R3F: OrbitControls is not part of the THREE namespace!\n\n// after\nimport { Canvas, extend } from '@react-three/fiber'\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nextend({ OrbitControls })\n<Canvas><orbitControls /></Canvas>","handlingStrategy":"validation","validationCode":"import * as THREE from 'three'\nimport { extend } from '@react-three/fiber'\n\n// Before rendering third-party elements, verify registration\nexport function ensureRegistered(name: string, ctor: unknown) {\n  if (!(name in (THREE as any))) extend({ [name]: ctor as any })\n}\nensureRegistered('OrbitControls', OrbitControls)","typeGuard":"import * as THREE from 'three'\nconst isThreeClass = (name: string): boolean => {\n  const pascal = name.charAt(0).toUpperCase() + name.slice(1)\n  return pascal in THREE || ['primitive'].includes(name)\n}","tryCatchPattern":"null","preventionTips":["Call extend() once at module scope, near the imports of the addon classes.","Explicitly import every class you reference via JSX so bundlers can't tree-shake it.","After upgrading three/R3F, smoke-test each custom JSX tag (typos fail only at render time)."],"tags":["react-three-fiber","extend","threejs","jsx","catalogue"],"backgroundTag":"unregistered-jsx-element","analyzedSha":"ff3899dbf43d2a88895fecf53c147192abfd7431","analyzedAt":"2026-08-28T10:16:38.568Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}