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

  1. 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).
  2. 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).
  3. 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

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


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