mrdoob/three.js · error · Error
setTitle: Unknown script
Error message
setTitle: Unknown script
What it means
Thrown by the three.js editor's Script panel setTitle() when it receives a script argument that is neither a script object nor one of the three recognized shader/program string keys ('vertexShader', 'fragmentShader', 'programInfo'). The switch in setTitle() has no case for any other string, so the default branch aborts. It is a defensive guard that mirrors the one in the editScript handler (error [1]); setTitle is called from that handler at Script.js:472, so this fires only if the upstream switch did not already throw on the same value.
Source
Thrown at editor/js/Script.js:417
case 'vertexShader':
title.setValue( object.material.name + ' / ' + strings.getKey( 'script/title/vertexShader' ) );
break;
case 'fragmentShader':
title.setValue( object.material.name + ' / ' + strings.getKey( 'script/title/fragmentShader' ) );
break;
case 'programInfo':
title.setValue( object.material.name + ' / ' + strings.getKey( 'script/title/programInfo' ) );
break;
default:
throw new Error( 'setTitle: Unknown script' );
}
}
}
signals.editScript.add( function ( object, script ) {
let mode, source;
if ( typeof ( script ) === 'object' ) {
mode = 'javascript';
source = script.source;
} else {
View on GitHub (pinned to da05705fa3)
Solutions
- If you added a new editable script kind, add a case for it in BOTH the setTitle switch (Script.js:398) and the editScript switch (Script.js:436), using the same string literal.
- If the value is unexpected, locate the dispatching code (grep for signals.editScript.dispatch) and correct the string to one of 'vertexShader' | 'fragmentShader' | 'programInfo', or pass a script object for a JS edit.
- If you are calling the editor programmatically, pass a script object ({name, source}) for JavaScript editing rather than an ad-hoc string.
Example fix
// before signals.editScript.dispatch( object, 'fragShader' ); // after — use the exact key the switches recognize signals.editScript.dispatch( object, 'fragmentShader' ); // or, when adding support for a new stage, extend BOTH switches: // setTitle switch: case 'computeShader': title.setValue( object.material.name + ' / compute' ); break; // editScript switch: case 'computeShader': mode = 'glsl'; source = object.material.computeShader || ''; break;
Defensive patterns
Strategy: validation
Validate before calling
// Whitelist the script keys the editor recognizes before dispatching.
const SCRIPT_KEYS = new Set( [ 'vertexShader', 'fragmentShader', 'programInfo' ] );
function dispatchEditScript( object, script ) {
if ( typeof script === 'string' && ! SCRIPT_KEYS.has( script ) ) {
throw new TypeError( `Unsupported editScript key: ${script}` );
}
signals.editScript.dispatch( object, script );
} Type guard
// Distinguish a script object from a recognized shader/program string key.
function isKnownScriptKey( v ) {
return typeof v === 'string' &&
( v === 'vertexShader' || v === 'fragmentShader' || v === 'programInfo' );
}
function isScriptObject( v ) {
return v !== null && typeof v === 'object' && typeof v.source === 'string';
}
function isEditableScript( v ) {
return isScriptObject( v ) || isKnownScriptKey( v );
} Try / catch
// Wrap custom editor wiring so an unknown key degrades gracefully.
try {
signals.editScript.dispatch( object, script );
} catch ( err ) {
if ( /setTitle: Unknown script|editScript: Unknown script/.test( err.message ) ) {
console.error( 'editScript rejected key; falling back to programInfo', script );
signals.editScript.dispatch( object, 'programInfo' );
} else throw err;
} Prevention
- Keep the two switches (editScript at Script.js:436 and setTitle at Script.js:398) in sync whenever you add a script kind.
- Centralize the list of valid string keys in one constant and drive both switches from it.
- Prefer dispatching a script object for JS edits and the exact literals for shader edits.
When it happens
Trigger: Dispatching signals.editScript with a string value other than 'vertexShader', 'fragmentShader', or 'programInfo' (e.g. a typo like 'fragShader', or a newly introduced shader stage such as 'computeShader'). In the shipping editor the only dispatchers are Sidebar.Material.Program.js (which sends exactly those three literals) and Sidebar.Script.js (which sends a script object), so this is reached only by a custom/modified dispatch site.
Common situations: Extending the editor to edit additional shader stages or new script kinds without adding the matching case to both switches. Third-party editor plugins that call signals.editScript.dispatch() directly with an unsupported string. Refactors that rename a key in one place but not the other (the two switches must stay in sync).
Related errors
- editScript: Unknown script
- unknown type for ${primitiveName}:${ndx} param: ${name}
- unsupported shape type: ${type}
- THREE.KeyframeTrack: Unsupported typeName: ${typeName}
- THREE.WebGLProgram: Can not resolve #include <' + include +
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/2da8e6828b7c1609.
Report an issue: GitHub.