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
- For every data-primitive="X" in the page, ensure diagrams.X is defined (it should expose create() and, for interactive params, a ui map).
- Check for case sensitivity / typos: the attribute value must exactly equal the diagrams key.
- 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
- data-primitive values are case-sensitive and must equal the diagrams key exactly.
- Register every primitive's create() (and ui map if interactive) before adding the HTML block.
- Use data-primitive for parameterized demos and data-diagram for static ones.
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
- no diagram ${name}
- no diagram ${name}
- no ui for ${primitiveName}:${ndx} param: ${name}
- unknown type for ${primitiveName}:${ndx} param: ${name}
- "transform stack empty!
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/03341b073cf2c131.
Report an issue: GitHub.