mrdoob/three.js · error · Error

no primitive ${name}

Error message

no primitive ${name}

What it means

Thrown by threejs-primitives.js createPrimitiveDOM() when an element carries data-primitive="X" but the file's diagrams object has no key X. Despite the message saying 'no primitive', the lookup is into the shared diagrams map keyed by the data-primitive value. The primitive page uses data-primitive (not data-diagram) for these parameterized geometry demos.

Source

Thrown at manual/resources/threejs-primitives.js:880

		parent.appendChild( elem );
		return elem;

	}

	function addDiv( parent, className ) {

		return addElem( parent, 'div', className );

	}

	function createPrimitiveDOM( base ) {

		const name = base.dataset.primitive;
		const info = diagrams[ name ];
		if ( ! info ) {

			throw new Error( `no primitive ${name}` );

		}

		const text = base.innerHTML;
		base.innerHTML = '';

		const pair = addDiv( base, 'pair' );
		const elem = addDiv( pair, 'shape' );

		const right = addDiv( pair, 'desc' );
		addDeepLink( right, '#', `#${base.id}` );
		addLink( right, name );
		addDiv( right, '.note' ).innerHTML = text;

		// I get that this is super brittle. I think I'd have to
		// work through a bunch more examples to come up with a better
		// structure. Also, I don't want to generate actual code and
		// use eval. (maybe a bad striction)

View on GitHub (pinned to da05705fa3)

Solutions

  1. For every data-primitive="X" in the page, ensure diagrams.X is defined (it should expose create() and, for interactive params, a ui map).
  2. Check for case sensitivity / typos: the attribute value must exactly equal the diagrams key.
  3. Remove the data-primitive attribute if the element is not a primitive demo.

Example fix

// HTML: <div data-primitive="LatheGeometry"></div>
// before — diagrams lacks 'LatheGeometry'
const diagrams = {
  CylinderGeometry: { create: makeCylinder, ui: { /*...*/ } },
};

// after
const diagrams = {
  CylinderGeometry: { create: makeCylinder, ui: { /*...*/ } },
  LatheGeometry: { create: makeLathe, ui: { /*...*/ } },
};
Defensive patterns

Strategy: validation

Validate before calling

function assertPrimitivesRegistered( diagrams ) {
  const missing = [ ...document.querySelectorAll( '[data-primitive]' ) ]
    .map( el => el.dataset.primitive )
    .filter( name => ! diagrams[ name ] );
  if ( missing.length ) throw new Error( `Unregistered primitives: ${missing.join( ', ' )}` );
}

Type guard

function isPrimitiveInfo( v ) {
  return v !== null && typeof v === 'object' && typeof v.create === 'function';
}

Try / catch

document.querySelectorAll( '[data-primitive]' ).forEach( base => {
  const info = diagrams[ base.dataset.primitive ];
  if ( ! info ) { console.warn( 'skip unknown primitive:', base.dataset.primitive ); return; }
  try { createPrimitiveDOM( base ); } catch ( e ) { console.error( base.dataset.primitive, e ); }
} );

Prevention

When it happens

Trigger: Adding <div data-primitive="BoxGeometry"> to the primitives lesson without a diagrams.BoxGeometry entry. A typo or case mismatch in the data-primitive value (the lookup is case-sensitive).

Common situations: Authoring a new primitive demo in the manual: you write the HTML block with data-primitive but forget to register the primitive factory in the diagrams map. Renaming a primitive builder key but not the HTML attribute.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/03341b073cf2c131. Report an issue: GitHub.