mrdoob/three.js · error

THREE.PropertyBinding: Cannot parse trackName: ${trackName}

Error message

THREE.PropertyBinding: Cannot parse trackName: ${trackName}

What it means

Thrown by PropertyBinding.parseTrackName() when the track name fails to match the binding grammar regex _trackRe entirely. The regex requires, at minimum, a '.propertyName' suffix; the optional parts are a directory prefix (a/b/ or a:b:), a node name, and an object/index accessor. A string with no dot-segmented property tail — e.g. a bare 'position' or random text — yields no match and is rejected.

Source

Thrown at src/animation/PropertyBinding.js:215

	 * - nodeName.material.property[accessor]
	 * - uuid.property[accessor]
	 * - uuid.objectName[objectIndex].propertyName[propertyIndex]
	 * - parentName/nodeName.property
	 * - parentName/parentName/nodeName.property[index]
	 * - .bone[Armature.DEF_cog].position
	 * - scene:helium_balloon_model:helium_balloon_model.position
	 *
	 * @static
	 * @param {string} trackName - The track name to parse.
	 * @return {Object} The parsed track name as an object.
	 */
	static parseTrackName( trackName ) {

		const matches = _trackRe.exec( trackName );

		if ( matches === null ) {

			throw new Error( 'THREE.PropertyBinding: Cannot parse trackName: ' + trackName );

		}

		const results = {
			// directoryName: matches[ 1 ], // (tschw) currently unused
			nodeName: matches[ 2 ],
			objectName: matches[ 3 ],
			objectIndex: matches[ 4 ],
			propertyName: matches[ 5 ], // required
			propertyIndex: matches[ 6 ]
		};

		const lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );

		if ( lastDot !== undefined && lastDot !== - 1 ) {

			const objectName = results.nodeName.substring( lastDot + 1 );

View on GitHub (pinned to da05705fa3)

Solutions

  1. Give the track a name of the form 'nodeName.property' (e.g. 'Armature.Bone.position', '.bone[Rig].quaternion', 'material.opacity').
  2. Avoid reserved characters ([ ] . : /) inside node names, or escape the structure using the documented accessor syntax.
  3. Validate names against the grammar (a dot-delimited property tail is mandatory) before constructing tracks.

Example fix

// before — no property path
new VectorKeyframeTrack( 'head', times, values );
// -> 'Cannot parse trackName: head'

// after — node + property
new VectorKeyframeTrack( 'Head.position', times, values );
Defensive patterns

Strategy: validation

Validate before calling

// A track name MUST contain a dot-delimited property tail.
const TRACK_NAME_RE = /(?:[\w.-]+[\/:])?[^\[\]\.:\/]+(?:\.(?:material|materials|bones|map)\[?[\w.\-\]]*\]?)?\.([^\[\]\.:\/]+)(?:\[([^\]]+)\])?$/;
function validateTrackName( name ) {
  if ( typeof name !== 'string' || ! name.includes( '.' ) ) {
    throw new Error( `Invalid track name (needs a '.property' tail): ${name}` );
  }
}

Type guard

function isParsableTrackName( name ) {
  return typeof name === 'string' && name.includes( '.' ) && name.trim().length > 0;
}

Try / catch

try {
  THREE.PropertyBinding.parseTrackName( name );
} catch ( err ) {
  if ( /Cannot parse trackName/.test( err.message ) ) {
    console.error( 'Skipping track with unparseable name:', name );
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a KeyframeTrack whose name lacks a property path (no dot, e.g. 'position' instead of 'SomeNode.position'). A track name with only reserved-char gibberish that the node/property groups cannot capture. Building tracks from identifiers that are object names rather than property bindings.

Common situations: Hand-authoring animation tracks and using the bone/object name as the track name without appending '.position'/'.quaternion'. Loading animations where an exporter emitted node-name-only track identifiers. Unicode or reserved characters ([ ] . : /) in node names that break the word-character groups.

Related errors


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