mrdoob/three.js · error
THREE.KeyframeTrack: track type undefined, can not parse
Error message
THREE.KeyframeTrack: track type undefined, can not parse
What it means
Thrown by parseKeyframeTrack() when a track object in an AnimationClip JSON has no 'type' field at all. The type is required to select the KeyframeTrack subclass via getTrackTypeForValueTypeName(); without it, parsing cannot proceed. This fires before the unsupported-type-name check (error [14]).
Source
Thrown at src/animation/AnimationClip.js:458
case 'boolean':
return BooleanKeyframeTrack;
case 'string':
return StringKeyframeTrack;
}
throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
}
function parseKeyframeTrack( json ) {
if ( json.type === undefined ) {
throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
}
const trackType = getTrackTypeForValueTypeName( json.type );
if ( json.times === undefined ) {
const times = [], values = [];
AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
json.times = times;
json.values = values;
}
// derived classes can define a static parse method
if ( trackType.parse !== undefined ) {View on GitHub (pinned to da05705fa3)
Solutions
- Inspect each track in the clip JSON and add the missing 'type' field with a supported value-type name (e.g. 'vector3', 'quaternion', 'scalar').
- Re-export the clip from the source (Blender/glTF) rather than hand-editing, so type is always populated.
- If loading untrusted animation data, validate up front that every track has a non-empty type before calling AnimationClip.parse().
Example fix
// before
{ "tracks": [ { "name": "x.position", "times": [0], "values": [0] } ] }
// -> 'track type undefined, can not parse'
// after — add the type field
{ "tracks": [ { "name": "x.position", "type": "vector3", "times": [0], "values": [0,0,0] } ] } Defensive patterns
Strategy: validation
Validate before calling
function validateClipTracks( clipJson ) {
for ( const t of clipJson.tracks || [] ) {
if ( t.type === undefined ) throw new Error( `track '${t.name}' is missing 'type'` );
}
} Type guard
function trackHasType( track ) {
return track !== null && typeof track === 'object' && typeof track.type === 'string' && track.type.length > 0;
} Try / catch
try {
clip = AnimationClip.parse( json );
} catch ( err ) {
if ( /track type undefined/.test( err.message ) ) {
console.error( 'Skipping clip with untyped track(s).', json );
clip = null;
} else throw err;
} Prevention
- Always serialize tracks with a 'type' field; re-export rather than hand-edit clip JSON.
- Before AnimationClip.parse, assert every track has a non-empty type.
- Audit custom exporters to ensure type is emitted for every track.
When it happens
Trigger: An animation clip JSON whose tracks array contains an entry missing the type key. Manually constructing clip JSON and omitting type. A truncated/malformed serialization where the type field was dropped.
Common situations: Hand-editing exported animation JSON. A bug in a custom exporter that skips the type field for certain tracks. Loading a partially-corrupt clip file.
Related errors
- THREE.KeyframeTrack: Unsupported typeName: ${typeName}
- THREE.KeyframeTrack: track name is undefined
- THREE.PropertyBinding: can not parse propertyName from track
- unsupported interpolation for ${this.ValueTypeName} keyframe
- THREE.PropertyBinding: Cannot parse trackName: ${trackName}
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/bbb05c87f23340a9.
Report an issue: GitHub.