mrdoob/three.js · error

THREE.PropertyBinding: can not parse propertyName from track

Error message

THREE.PropertyBinding: can not parse propertyName from trackName: ${trackName}

What it means

Thrown by PropertyBinding.parseTrackName() as a secondary guard: the regex matched, but the propertyName capture group (match[5]) came back null or empty. Because the property regex segment (\.(WC+)) is the only mandatory part of _trackRe, reaching this branch typically means the supported-object-name reshuffling at line 230-245 consumed the trailing token, leaving no property — i.e. the track name's only dot-delimited tail was an allowlisted object name ('material'/'materials'/'bones'/'map') with no property after it.

Source

Thrown at src/animation/PropertyBinding.js:249

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

			// Object names must be checked against an allowlist. Otherwise, there
			// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
			// 'bar' could be the objectName, or part of a nodeName (which can
			// include '.' characters).
			if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {

				results.nodeName = results.nodeName.substring( 0, lastDot );
				results.objectName = objectName;

			}

		}

		if ( results.propertyName === null || results.propertyName.length === 0 ) {

			throw new Error( 'THREE.PropertyBinding: can not parse propertyName from trackName: ' + trackName );

		}

		return results;

	}

	/**
	 * Searches for a node in the hierarchy of the given root object by the given
	 * node name.
	 *
	 * @static
	 * @param {Object} root - The root object.
	 * @param {string|number} nodeName - The name of the node.
	 * @return {?Object} The found node. Returns `null` if no object was found.
	 */
	static findNode( root, nodeName ) {

View on GitHub (pinned to da05705fa3)

Solutions

  1. Append a concrete property after the object name: 'mesh.material.opacity', 'node.bones[0].position', 'sprite.map.repeat'.
  2. If you intended to target the object itself (not a property), reconsider — PropertyBinding animates properties/accessors, not whole objects.
  3. Validate that the track name ends in a property token after any allowlisted object name.

Example fix

// before — allowlisted object name but no property after it
new NumberKeyframeTrack( 'mesh.material', times, values );
// -> 'can not parse propertyName from trackName: mesh.material'

// after — target a property of the material
new NumberKeyframeTrack( 'mesh.material.opacity', times, values );
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_OBJECTS = new Set( [ 'material', 'materials', 'bones', 'map' ] );
// A name ending in an allowlisted object name with no property tail is the common trigger.
function endsWithBareObject( name ) {
  const tail = name.split( '.' ).pop();
  return ALLOWED_OBJECTS.has( tail );
}
function validateTrackNameHasProperty( name ) {
  if ( typeof name !== 'string' || endsWithBareObject( name ) ) {
    throw new Error( `Track name needs a property after the object: ${name}` );
  }
}

Type guard

const ALLOWED_OBJECTS = new Set( [ 'material', 'materials', 'bones', 'map' ] );
function trackNameHasPropertyTail( name ) {
  if ( typeof name !== 'string' ) return false;
  const parts = name.split( '.' );
  if ( parts.length < 2 ) return false;
  const tail = parts[ parts.length - 1 ];
  return ! ALLOWED_OBJECTS.has( tail ) && tail.length > 0;
}

Try / catch

try {
  THREE.PropertyBinding.parseTrackName( name );
} catch ( err ) {
  if ( /can not parse propertyName/.test( err.message ) ) {
    console.error( 'Track name ends in an object name with no property:', name );
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: A track name ending in '.material', '.materials', '.bones', or '.map' with no following property (e.g. 'mesh.material'), so the reshaping logic treats the token as objectName and leaves propertyName empty. Edge-case track names that the regex partially matches without capturing the property group.

Common situations: Animating 'material' as if it were a property rather than animating a property OF material (e.g. 'mesh.material' instead of 'mesh.material.opacity'). Building bindings from data where the property suffix was stripped.

Related errors


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