{"record":{"id":"9d82b4f4e5d22d89","repo":"mrdoob/three.js","slug":"three-propertybinding-cannot-parse-trackname-t","errorCode":null,"errorMessage":"THREE.PropertyBinding: Cannot parse trackName: ${trackName}","messagePattern":"THREE\\.PropertyBinding: Cannot parse trackName: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/animation/PropertyBinding.js","lineNumber":215,"sourceCode":"\t * - nodeName.material.property[accessor]\n\t * - uuid.property[accessor]\n\t * - uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t * - parentName/nodeName.property\n\t * - parentName/parentName/nodeName.property[index]\n\t * - .bone[Armature.DEF_cog].position\n\t * - scene:helium_balloon_model:helium_balloon_model.position\n\t *\n\t * @static\n\t * @param {string} trackName - The track name to parse.\n\t * @return {Object} The parsed track name as an object.\n\t */\n\tstatic parseTrackName( trackName ) {\n\n\t\tconst matches = _trackRe.exec( trackName );\n\n\t\tif ( matches === null ) {\n\n\t\t\tthrow new Error( 'THREE.PropertyBinding: Cannot parse trackName: ' + trackName );\n\n\t\t}\n\n\t\tconst results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ],\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ], // required\n\t\t\tpropertyIndex: matches[ 6 ]\n\t\t};\n\n\t\tconst lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );\n\n\t\tif ( lastDot !== undefined && lastDot !== - 1 ) {\n\n\t\t\tconst objectName = results.nodeName.substring( lastDot + 1 );\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/animation/PropertyBinding.js#L197-L233","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Give the track a name of the form 'nodeName.property' (e.g. 'Armature.Bone.position', '.bone[Rig].quaternion', 'material.opacity').","Avoid reserved characters ([ ] . : /) inside node names, or escape the structure using the documented accessor syntax.","Validate names against the grammar (a dot-delimited property tail is mandatory) before constructing tracks."],"exampleFix":"// before — no property path\nnew VectorKeyframeTrack( 'head', times, values );\n// -> 'Cannot parse trackName: head'\n\n// after — node + property\nnew VectorKeyframeTrack( 'Head.position', times, values );","handlingStrategy":"validation","validationCode":"// A track name MUST contain a dot-delimited property tail.\nconst TRACK_NAME_RE = /(?:[\\w.-]+[\\/:])?[^\\[\\]\\.:\\/]+(?:\\.(?:material|materials|bones|map)\\[?[\\w.\\-\\]]*\\]?)?\\.([^\\[\\]\\.:\\/]+)(?:\\[([^\\]]+)\\])?$/;\nfunction validateTrackName( name ) {\n  if ( typeof name !== 'string' || ! name.includes( '.' ) ) {\n    throw new Error( `Invalid track name (needs a '.property' tail): ${name}` );\n  }\n}","typeGuard":"function isParsableTrackName( name ) {\n  return typeof name === 'string' && name.includes( '.' ) && name.trim().length > 0;\n}","tryCatchPattern":"try {\n  THREE.PropertyBinding.parseTrackName( name );\n} catch ( err ) {\n  if ( /Cannot parse trackName/.test( err.message ) ) {\n    console.error( 'Skipping track with unparseable name:', name );\n    return null;\n  }\n  throw err;\n}","preventionTips":["Always name tracks as 'node.property' (or one of the documented binding forms).","Avoid reserved characters [ ] . : / inside node names.","Validate that a name has a dot-delimited property tail before constructing a track."],"tags":["animation","property-binding","parsing","track-name"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}