mrdoob/three.js · error · Error
editScript: Unknown script
Error message
editScript: Unknown script
What it means
Thrown by the three.js editor's editScript signal handler when the script argument is a string that is not 'vertexShader', 'fragmentShader', or 'programInfo'. The switch assigns mode/source for each known kind and its default branch throws. Because this handler runs before it calls setTitle(object, script) at Script.js:472, this error fires first and preempts error [0] for the same bad input. The two guards exist as a pair to keep the mode-assignment switch and the title switch consistent.
Source
Thrown at editor/js/Script.js:466
source = object.material.fragmentShader || '';
break;
case 'programInfo':
mode = 'json';
const json = {
defines: object.material.defines,
uniforms: object.material.uniforms,
attributes: object.material.attributes
};
source = JSON.stringify( json, null, '\t' );
break;
default:
throw new Error( 'editScript: Unknown script' );
}
}
setTitle( object, script );
currentMode = mode;
currentScript = script;
currentObject = object;
if ( mode === 'javascript' ) loadThreeDefs();
container.setDisplay( '' );
codemirror.setValue( source );
codemirror.clearHistory();
if ( mode === 'json' ) mode = { name: 'javascript', json: true };
codemirror.setOption( 'mode', mode );View on GitHub (pinned to da05705fa3)
Solutions
- Grep for every signals.editScript.dispatch(...) and confirm each string argument is one of 'vertexShader' | 'fragmentShader' | 'programInfo' (or that the argument is a script object).
- If you intended a new kind, add a matching case to the editScript switch (Script.js:436) that sets mode and source, AND to the setTitle switch (Script.js:398).
- If the dispatch is coming from Sidebar.Script.js with an object, ensure the object is not being stringified or replaced by a stray string before dispatch.
Example fix
// before — unhandled literal
switch ( script ) {
case 'vertexShader': /* ... */ break;
// ...
default: throw new Error( 'editScript: Unknown script' );
}
// after — add the missing case so mode/source are assigned
switch ( script ) {
case 'vertexShader': /* ... */ break;
case 'geometryShader':
mode = 'glsl';
source = object.material.geometryShader || '';
break;
// ...
default: throw new Error( 'editScript: Unknown script' );
} Defensive patterns
Strategy: validation
Validate before calling
const SCRIPT_KEYS = new Set( [ 'vertexShader', 'fragmentShader', 'programInfo' ] );
function safeEditScript( object, script ) {
if ( typeof script === 'string' && ! SCRIPT_KEYS.has( script ) ) {
throw new TypeError( `Unsupported editScript key: ${script}` );
}
signals.editScript.dispatch( object, script );
} Type guard
function isKnownScriptKey( v ) {
return v === 'vertexShader' || v === 'fragmentShader' || v === 'programInfo';
}
function isEditableScript( v ) {
if ( v !== null && typeof v === 'object' && typeof v.source === 'string' ) return true;
return isKnownScriptKey( v );
} Try / catch
try {
signals.editScript.dispatch( object, script );
} catch ( err ) {
if ( /editScript: Unknown script/.test( err.message ) ) {
console.error( 'Rejected editScript key, ignoring:', script );
} else throw err;
} Prevention
- Grep signals.editScript.dispatch to audit every call site for the three allowed literals.
- When adding a script kind, update both the mode/source switch and the title switch in the same commit.
- Route programmatic edits through a single helper that validates the key.
When it happens
Trigger: Any signals.editScript.dispatch(object, str) where str is not one of the three recognized literals. The stock editor never does this; it arises from custom dispatchers, editor plugins, or a key renamed on one side of the pair of switches.
Common situations: A plugin or fork that adds a new editable script type and updates the title switch but forgets the mode/source switch (or vice versa). Passing a DOM event name or a material UUID where the script key is expected. Copy-paste errors introducing an unhandled literal.
Related errors
- setTitle: 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/32adb1a76b6c5e6f.
Report an issue: GitHub.