mrdoob/three.js · error · Error

unknown type for ${primitiveName}:${ndx} param: ${name}

Error message

unknown type for ${primitiveName}:${ndx} param: ${name}

What it means

Thrown while generating an interactive control for a primitive parameter whose info.ui[name].type is not one of the three handled kinds: 'range', 'bool', or 'text'. The switch in the UI builder has a default that throws, naming the primitive, its index, and the parameter. Adding a new control visual (e.g. a color picker, select, vector) requires extending this switch.

Source

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

								const input = document.createElement( 'input' );
								input.type = 'text';
								params[ name ] = valueElem.textContent.slice( 1, - 1 );
								input.value = params[ name ];
								input.maxlength = ui.maxLength || 50;
								inputHolder.appendChild( input );
								input.addEventListener( 'input', () => {

									params[ name ] = input.value;
									valueElem.textContent = `'${input.value}'`;
									updateGeometry( root, info, params );

								} );
								break;

							}

							default:
								throw new Error( `unknown type for ${primitiveName}:${ndx} param: ${name}` );

						}

					} );

			} );

		} );

	} );

	document.querySelectorAll( '[data-diagram]' ).forEach( createDiagram );
	document.querySelectorAll( '[data-primitive]' ).forEach( createPrimitiveDOM );

}

View on GitHub (pinned to da05705fa3)

Solutions

  1. Set ui[name].type to one of the supported values: 'range' (numeric slider), 'bool' (checkbox), or 'text' (string input).
  2. If you need a new control type, add a case to the switch at threejs-primitives.js:1112 that builds the appropriate input and updates params[name] + valueElem on change.
  3. Check for casing: use lowercase 'bool', not 'boolean'.

Example fix

// before — 'color' is not handled by the switch
ui: {
  tint: { type: 'color' },
}

// after — use a supported type, or extend the switch
ui: {
  tint: { type: 'text' }, // e.g. accept a hex string
}
// or add: case 'color': { /* build <input type="color"> ... */ break; }
Defensive patterns

Strategy: type-guard

Validate before calling

const UI_TYPES = new Set( [ 'range', 'bool', 'text' ] );
function assertUiTypes( info ) {
  if ( ! info.ui ) return;
  for ( const [ name, entry ] of Object.entries( info.ui ) ) {
    if ( ! UI_TYPES.has( entry.type ) ) throw new Error( `bad ui.type for ${name}: ${entry.type}` );
  }
}

Type guard

const UI_TYPES = new Set( [ 'range', 'bool', 'text' ] );
function isUiEntry( v ) {
  return v !== null && typeof v === 'object' && UI_TYPES.has( v.type );
}

Try / catch

switch ( ui.type ) {
  case 'range': /* ... */ break;
  case 'bool':  /* ... */ break;
  case 'text':  /* ... */ break;
  default:
    console.warn( `unsupported ui.type ${ui.type} for ${name}; rendering text input` );
    ui.type = 'text'; // fallback
}

Prevention

When it happens

Trigger: A primitive's ui entry with type: 'color', type: 'select', type: 'number', or any value outside {'range','bool','text'}. A typo in the type string (e.g. 'Range', 'boolean' instead of 'bool').

Common situations: Extending the primitives lesson with a new parameter kind and setting ui.type to something the builder does not yet handle. Using 'boolean' (which the type-name switch in AnimationClip accepts) instead of the exact 'bool' this UI builder requires.

Related errors


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