mrdoob/three.js · error
unsupported interpolation for ${this.ValueTypeName} keyframe
Error message
unsupported interpolation for ${this.ValueTypeName} keyframe track named ${this.name} What it means
Thrown by KeyframeTrack.setInterpolation() in the fatal branch: the requested interpolation constant has no factory method on this track subclass AND createInterpolant is undefined AND the requested interpolation is already the track's DefaultInterpolation (so there is nothing left to fall back to). Most unsupported-interpolation cases are non-fatal — the code warns and falls back to DefaultInterpolation — so this throw only occurs when even the default cannot produce an interpolant, meaning the track subclass is fundamentally incomplete.
Source
Thrown at src/animation/KeyframeTrack.js:224
break;
}
if ( factoryMethod === undefined ) {
const message = 'unsupported interpolation for ' +
this.ValueTypeName + ' keyframe track named ' + this.name;
if ( this.createInterpolant === undefined ) {
// fall back to default, unless the default itself is messed up
if ( interpolation !== this.DefaultInterpolation ) {
this.setInterpolation( this.DefaultInterpolation );
} else {
throw new Error( message ); // fatal, in this case
}
}
warn( 'KeyframeTrack:', message );
return this;
}
this.createInterpolant = factoryMethod;
return this;
}
/**
* Returns the current interpolation type.View on GitHub (pinned to da05705fa3)
Solutions
- If you authored the track subclass, implement the relevant InterpolantFactoryMethod* (or override createInterpolant) so DefaultInterpolation resolves to a factory.
- If calling setInterpolation on a built-in discrete-only track (boolean/string), use InterpolateDiscrete rather than Linear/Smooth.
- If the throw comes from a built-in track, ensure you are on a current three.js version — a missing default factory on a stock track is a bug.
Example fix
// before — custom track with no factory; constructor's setInterpolation throws
class MyTrack extends KeyframeTrack {
// no InterpolantFactoryMethod* defined, createInterpolant undefined
}
new MyTrack( 'x.value', [0,1], [0,1] ); // fatal
// after — provide a default interpolant factory
MyTrack.prototype.InterpolantFactoryMethodLinear =
( times, values, sample ) => new LinearInterpolant( times, values, sample ); Defensive patterns
Strategy: validation
Validate before calling
function safeSetInterpolation( track, interpolation ) {
// Only request interpolations the track type can honour.
const hasFactory = ( fn ) => typeof fn === 'function';
const ok = interpolation === THREE.InterpolateDiscrete && hasFactory( track.InterpolantFactoryMethodDiscrete )
|| interpolation === THREE.InterpolateLinear && hasFactory( track.InterpolantFactoryMethodLinear )
|| interpolation === THREE.InterpolateSmooth && hasFactory( track.InterpolantFactoryMethodSmooth )
|| interpolation === THREE.InterpolateBezier && hasFactory( track.InterpolantFactoryMethodBezier );
if ( ! ok ) throw new Error( `track cannot honour interpolation ${interpolation}` );
track.setInterpolation( interpolation );
} Type guard
function trackSupportsInterpolation( track, interpolation ) {
const map = {
[ THREE.InterpolateDiscrete ]: 'InterpolantFactoryMethodDiscrete',
[ THREE.InterpolateLinear ]: 'InterpolantFactoryMethodLinear',
[ THREE.InterpolateSmooth ]: 'InterpolantFactoryMethodSmooth',
[ THREE.InterpolateBezier ]: 'InterpolantFactoryMethodBezier',
};
return typeof track[ map[ interpolation ] ] === 'function';
} Try / catch
try {
track.setInterpolation( THREE.InterpolateSmooth );
} catch ( err ) {
if ( /unsupported interpolation/.test( err.message ) ) {
console.warn( 'smooth unsupported; falling back to discrete' );
track.setInterpolation( THREE.InterpolateDiscrete );
} else throw err;
} Prevention
- Use InterpolateDiscrete for boolean/string tracks; they have no linear/smooth factory.
- When subclassing KeyframeTrack, implement the factory methods (or override createInterpolant).
- Check that the requested interpolation has a factory before calling setInterpolation.
When it happens
Trigger: Subclassing KeyframeTrack without defining InterpolantFactoryMethodLinear/Smooth/Discrete/Bezier and without overriding createInterpolant, then constructing it (the constructor calls setInterpolation with DefaultInterpolation). Calling setInterpolation(InterpolateSmooth) on a track type (like StringKeyframeTrack or BooleanKeyframeTrack) that only supports InterpolateDiscrete after the default-discrete fallback already failed to find a factory.
Common situations: Writing a custom KeyframeTrack subclass and forgetting to provide an interpolant factory. Downgrading a track's interpolation to one its value type cannot honour (e.g. smooth-interpolating a boolean track) in an environment where the discrete factory was also not wired.
Related errors
- THREE.KeyframeTrack: Unsupported typeName: ${typeName}
- THREE.KeyframeTrack: track type undefined, can not parse
- THREE.KeyframeTrack: track name is undefined
- THREE.Interpolant: Call to abstract method.
- THREE.PropertyBinding: Cannot parse trackName: ${trackName}
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/169cafc0008ac208.
Report an issue: GitHub.