{"record":{"id":"ddfe497b32aac928","repo":"mrdoob/three.js","slug":"unknown-type-for-primitivename-ndx-param","errorCode":null,"errorMessage":"unknown type for ${primitiveName}:${ndx} param: ${name}","messagePattern":"unknown type for (.+?):(.+?) param: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"manual/resources/threejs-primitives.js","lineNumber":1184,"sourceCode":"\t\t\t\t\t\t\t\tconst input = document.createElement( 'input' );\n\t\t\t\t\t\t\t\tinput.type = 'text';\n\t\t\t\t\t\t\t\tparams[ name ] = valueElem.textContent.slice( 1, - 1 );\n\t\t\t\t\t\t\t\tinput.value = params[ name ];\n\t\t\t\t\t\t\t\tinput.maxlength = ui.maxLength || 50;\n\t\t\t\t\t\t\t\tinputHolder.appendChild( input );\n\t\t\t\t\t\t\t\tinput.addEventListener( 'input', () => {\n\n\t\t\t\t\t\t\t\t\tparams[ name ] = input.value;\n\t\t\t\t\t\t\t\t\tvalueElem.textContent = `'${input.value}'`;\n\t\t\t\t\t\t\t\t\tupdateGeometry( root, info, params );\n\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tthrow new Error( `unknown type for ${primitiveName}:${ndx} param: ${name}` );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\n\t\t\t} );\n\n\t\t} );\n\n\t} );\n\n\tdocument.querySelectorAll( '[data-diagram]' ).forEach( createDiagram );\n\tdocument.querySelectorAll( '[data-primitive]' ).forEach( createPrimitiveDOM );\n\n}\n","sourceCodeStart":1166,"sourceCodeEnd":1200,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/manual/resources/threejs-primitives.js#L1166-L1200","documentation":"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.","triggerScenarios":"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').","commonSituations":"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.","solutions":["Set ui[name].type to one of the supported values: 'range' (numeric slider), 'bool' (checkbox), or 'text' (string input).","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.","Check for casing: use lowercase 'bool', not 'boolean'."],"exampleFix":"// before — 'color' is not handled by the switch\nui: {\n  tint: { type: 'color' },\n}\n\n// after — use a supported type, or extend the switch\nui: {\n  tint: { type: 'text' }, // e.g. accept a hex string\n}\n// or add: case 'color': { /* build <input type=\"color\"> ... */ break; }","handlingStrategy":"type-guard","validationCode":"const UI_TYPES = new Set( [ 'range', 'bool', 'text' ] );\nfunction assertUiTypes( info ) {\n  if ( ! info.ui ) return;\n  for ( const [ name, entry ] of Object.entries( info.ui ) ) {\n    if ( ! UI_TYPES.has( entry.type ) ) throw new Error( `bad ui.type for ${name}: ${entry.type}` );\n  }\n}","typeGuard":"const UI_TYPES = new Set( [ 'range', 'bool', 'text' ] );\nfunction isUiEntry( v ) {\n  return v !== null && typeof v === 'object' && UI_TYPES.has( v.type );\n}","tryCatchPattern":"switch ( ui.type ) {\n  case 'range': /* ... */ break;\n  case 'bool':  /* ... */ break;\n  case 'text':  /* ... */ break;\n  default:\n    console.warn( `unsupported ui.type ${ui.type} for ${name}; rendering text input` );\n    ui.type = 'text'; // fallback\n}","preventionTips":["Restrict ui.type to the supported set: range, bool, text (lowercase).","If you need a new control, add the case to the switch at threejs-primitives.js:1112.","Lint ui definitions to reject unknown types before rendering."],"tags":["manual","primitives","ui","switch-enum","lesson"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}