greensock/GSAP · error

Please gsap.registerPlugin(PathEditor)

Error message

Please gsap.registerPlugin(PathEditor)

What it means

PathEditor's _initCore assigns gsap = gsap || core || _win.gsap || console.warn("Please gsap.registerPlugin(PathEditor)"). If no gsap core is reachable (not loaded globally, not passed to _initCore, and registerPlugin never ran), it warns that registration is required and the editor cannot initialize.

Solutions

  1. Call gsap.registerPlugin(PathEditor) after importing gsap and the plugin
  2. Ensure gsap core is loaded/evaluated before PathEditor's constructor runs
  3. If using the internal API, pass the gsap instance to PathEditor._initCore(core)
  4. Confirm your build includes PathEditor (Club GSAP plugin)

Example fix

// before
import { PathEditor } from 'gsap/PathEditor';
const editor = new PathEditor(pathElement);
// after
import { gsap } from 'gsap';
import { PathEditor } from 'gsap/PathEditor';
gsap.registerPlugin(PathEditor);
const editor = new PathEditor(pathElement);
Defensive patterns

Strategy: validation

Validate before calling

import { gsap } from 'gsap';
import { PathEditor } from 'gsap/PathEditor';
gsap.registerPlugin(PathEditor);
if (!gsap.core.globals().PathEditor) throw new Error('PathEditor not registered / not available');

Try / catch

try {
  const editor = new PathEditor(el);
} catch (e) {
  console.error('PathEditor init failed — check gsap registration and license build', e);
}

Prevention

When it happens

Trigger: new PathEditor(...) without gsap.registerPlugin(PathEditor), module builds where gsap is not on window and no core was passed, or the plugin script loaded before gsap core.

Common situations: Module bundler setups where gsap isn't a global, forgetting registration with the Club GSAP PathEditor plugin, load-order mistakes in script tags, or using the plugin without the required GSAP membership build.

Related errors


AI-assisted analysis of greensock/GSAP@13e2b79054 (2026-08-29). Data as JSON: /api/errors/1b602a69f5a0c028. Report an issue: GitHub.

Appendix: source

Thrown at src/utils/PathEditor.js:160

	_callback = (type, self, param) => {
		let callback = self.vars[type];
		if (callback) {
			callback.call(self.vars.callbackScope || self, param || self);
		}
		return self;
	},
	_copyElement,
	_resetSelection = () => {
		_copyElement.style.display = "block";
		_copyElement.select();
		_copyElement.style.display = "none";
	},
	_coreInitted,
	_initCore = (core) => {
		_doc = document;
		_win = window;
		_body = _doc.body;
		gsap = gsap || core || _win.gsap || console.warn("Please gsap.registerPlugin(PathEditor)");
		_context = (gsap && gsap.core.context) || function() {};
		_tempDiv = _createElement("div");
		_copyElement = _createElement("textarea");
		_copyElement.style.display = "none";
		_body && _body.appendChild(_copyElement);
		_touchEventLookup = (function(types) { //we create an object that makes it easy to translate touch event types into their "pointer" counterparts if we're in a browser that uses those instead. Like IE10 uses "MSPointerDown" instead of "touchstart", for example.
			let standard = types.split(","),
				converted = ((_tempDiv.onpointerdown !== undefined) ? "pointerdown,pointermove,pointerup,pointercancel" : (_tempDiv.onmspointerdown !== undefined) ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","),
				obj = {},
				i = 4;
			while (--i > -1) {
				obj[standard[i]] = converted[i];
				obj[converted[i]] = standard[i];
			}
			return obj;
		}("touchstart,touchmove,touchend,touchcancel"));
		SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(e) { //adds Chrome support
			return e.getScreenCTM().inverse().multiply(this.getScreenCTM());

View on GitHub (pinned to 13e2b79054)