{"record":{"id":"169cafc0008ac208","repo":"mrdoob/three.js","slug":"unsupported-interpolation-for-this-valuetypename","errorCode":null,"errorMessage":"unsupported interpolation for ${this.ValueTypeName} keyframe track named ${this.name}","messagePattern":"unsupported interpolation for (.+?) keyframe track named (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/animation/KeyframeTrack.js","lineNumber":224,"sourceCode":"\t\t\t\tbreak;\n\n\t\t}\n\n\t\tif ( factoryMethod === undefined ) {\n\n\t\t\tconst message = 'unsupported interpolation for ' +\n\t\t\t\tthis.ValueTypeName + ' keyframe track named ' + this.name;\n\n\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\twarn( 'KeyframeTrack:', message );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tthis.createInterpolant = factoryMethod;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Returns the current interpolation type.","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/animation/KeyframeTrack.js#L206-L242","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — custom track with no factory; constructor's setInterpolation throws\nclass MyTrack extends KeyframeTrack {\n  // no InterpolantFactoryMethod* defined, createInterpolant undefined\n}\nnew MyTrack( 'x.value', [0,1], [0,1] ); // fatal\n\n// after — provide a default interpolant factory\nMyTrack.prototype.InterpolantFactoryMethodLinear =\n  ( times, values, sample ) => new LinearInterpolant( times, values, sample );","handlingStrategy":"validation","validationCode":"function safeSetInterpolation( track, interpolation ) {\n  // Only request interpolations the track type can honour.\n  const hasFactory = ( fn ) => typeof fn === 'function';\n  const ok = interpolation === THREE.InterpolateDiscrete && hasFactory( track.InterpolantFactoryMethodDiscrete )\n    || interpolation === THREE.InterpolateLinear && hasFactory( track.InterpolantFactoryMethodLinear )\n    || interpolation === THREE.InterpolateSmooth && hasFactory( track.InterpolantFactoryMethodSmooth )\n    || interpolation === THREE.InterpolateBezier && hasFactory( track.InterpolantFactoryMethodBezier );\n  if ( ! ok ) throw new Error( `track cannot honour interpolation ${interpolation}` );\n  track.setInterpolation( interpolation );\n}","typeGuard":"function trackSupportsInterpolation( track, interpolation ) {\n  const map = {\n    [ THREE.InterpolateDiscrete ]: 'InterpolantFactoryMethodDiscrete',\n    [ THREE.InterpolateLinear ]: 'InterpolantFactoryMethodLinear',\n    [ THREE.InterpolateSmooth ]: 'InterpolantFactoryMethodSmooth',\n    [ THREE.InterpolateBezier ]: 'InterpolantFactoryMethodBezier',\n  };\n  return typeof track[ map[ interpolation ] ] === 'function';\n}","tryCatchPattern":"try {\n  track.setInterpolation( THREE.InterpolateSmooth );\n} catch ( err ) {\n  if ( /unsupported interpolation/.test( err.message ) ) {\n    console.warn( 'smooth unsupported; falling back to discrete' );\n    track.setInterpolation( THREE.InterpolateDiscrete );\n  } else throw err;\n}","preventionTips":["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."],"tags":["animation","keyframe","interpolation","subclass"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}