{"record":{"id":"76226b1e8749795d","repo":"mrdoob/three.js","slug":"three-interpolant-call-to-abstract-method","errorCode":null,"errorMessage":"THREE.Interpolant: Call to abstract method.","messagePattern":"THREE\\.Interpolant: Call to abstract method\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/math/Interpolant.js","lineNumber":300,"sourceCode":"\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Copies a sample value to the result buffer.\n\t *\n\t * @abstract\n\t * @param {number} i1 - An index into the sample value buffer.\n\t * @param {number} t0 - The previous interpolation factor.\n\t * @param {number} t - The current interpolation factor.\n\t * @param {number} t1 - The next interpolation factor.\n\t * @return {TypedArray} The result buffer.\n\t */\n\tinterpolate_( /* i1, t0, t, t1 */ ) {\n\n\t\tthrow new Error( 'THREE.Interpolant: Call to abstract method.' );\n\t\t// implementations shall return this.resultBuffer\n\n\t}\n\n\t/**\n\t * Optional method that is executed when the interval has changed.\n\t *\n\t * @param {number} i1 - An index into the sample value buffer.\n\t * @param {number} t0 - The previous interpolation factor.\n\t * @param {number} t - The current interpolation factor.\n\t */\n\tintervalChanged_( /* i1, t0, t1 */ ) {\n\n\t\t// empty\n\n\t}\n\n}","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/math/Interpolant.js#L282-L318","documentation":"The base Interpolant class declares interpolate_() as abstract - it throws if called. Concrete subclasses (LinearInterpolant, DiscreteInterpolant, CubicInterpolant, etc.) override interpolate_() with the actual sampling math. The base class cannot interpolate because the algorithm depends on the subclass-specific value structure.","triggerScenarios":"Instantiating new THREE.Interpolant(...) directly and calling .evaluate(). Also subclassing Interpolant but forgetting to override interpolate_(). Or an animation/morph/property binding resolving to the base Interpolant type because no concrete interpolant was registered for the keyframe track type.","commonSituations":"Writing a custom KeyframeTrack subclass without supplying a matching interpolant. Library/extension code that accidentally references the abstract base. Mistakenly using Interpolant as a generic interpolator instead of LinearInterpolant.","solutions":["Use a concrete subclass: THREE.LinearInterpolant, THREE.DiscreteInterpolant, THREE.CubicInterpolant, or THREE.QuaternionLinearInterpolant.","If subclassing Interpolant, implement interpolate_(i1, t0, t, t1) returning this.resultBuffer.","For animation tracks, use the standard KeyframeTrack subclasses which select the correct interpolant automatically.","If the error surfaces from internal animation, check that your KeyframeTrack has a valid interpolation name (InterpolateLinear, InterpolateDiscrete, InterpolateSmooth)."],"exampleFix":"// before: instantiating the abstract base\nconst interp = new THREE.Interpolant(times, values, 3);\ninterp.evaluate(1.5); // throws 'Call to abstract method'\n\n// after: use a concrete interpolant\nconst interp = new THREE.LinearInterpolant(times, values, 3);\ninterp.evaluate(1.5);","handlingStrategy":"type-guard","validationCode":"function makeInterpolant(times, values, stride, interpolation = 'linear') {\n  switch (interpolation) {\n    case 'linear':    return new THREE.LinearInterpolant(times, values, stride);\n    case 'discrete':  return new THREE.DiscreteInterpolant(times, values, stride);\n    case 'cubic':     return new THREE.CubicInterpolant(times, values, stride);\n    default: throw new Error(`Unknown interpolation: ${interpolation}`);\n  }\n}","typeGuard":"import { Interpolant } from 'three';\n\nfunction isConcreteInterpolant(obj) {\n  return obj instanceof Interpolant && obj.constructor !== Interpolant;\n}","tryCatchPattern":null,"preventionTips":["Never instantiate the base Interpolant directly.","If subclassing Interpolant, override interpolate_(i1, t0, t, t1).","Use the standard KeyframeTrack subclasses for animation so the interpolant is chosen automatically."],"tags":["threejs","interpolant","abstract-method","animation","keyframe"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}