NativeScript/NativeScript · error · Error

Abstract method call

Error message

Abstract method call

What it means

The Transition base class on Android declares animateIOSTransition as an abstract-like method whose default implementation throws 'Abstract method call' (index.android.ts:39). It is a deliberate stub: only concrete Transition subclasses that implement iOS-style transition hooks should be invoked this way. Hitting it means a transition object lacking the required override was used where a fully implemented transition is expected.

Source

Thrown at packages/core/ui/transition/index.android.ts:39

		this._interpolator = curve ? _resolveAnimationCurve(curve) : _defaultInterpolator();
		transitionId++;
		this.id = transitionId;
	}

	public getDuration(): number {
		return this._duration;
	}

	public setDuration(value: number) {
		this._duration = value;
	}

	public getCurve(): android.view.animation.Interpolator {
		return this._interpolator;
	}

	public animateIOSTransition(transitionContext: any, fromViewCtrl: any, toViewCtrl: any, operation: any): void {
		throw new Error('Abstract method call');
	}

	public createAndroidAnimator(transitionType: string): android.animation.Animator {
		throw new Error('Abstract method call');
	}

	public toString(): string {
		return `Transition@${this.id}`;
	}
}

View on GitHub (pinned to 6800aefa65)

Solutions

  1. Use a concrete built-in transition (FadeTransition, SlideTransition, etc.) instead of the base Transition class.
  2. If writing a custom transition, override animateIOSTransition in your subclass and implement the iOS transition logic (or leave it as a no-op for Android-only transitions).
  3. Check the object actually being passed is the subclass instance, not the base class, at the call site.
  4. Compare your subclass against the built-in transitions in packages/core/ui/transition to see which methods are expected to be overridden.

Example fix

// before
const transition = new Transition(300); // base class, no override
// after
class MyTransition extends Transition {
  animateIOSTransition(transitionContext, fromViewCtrl, toViewCtrl, operation) {
    // implement or intentionally no-op for Android-only transitions
  }
}
const transition = new MyTransition(300);
Defensive patterns

Strategy: type-guard

Validate before calling

function hasIosTransition(t) {
  return t && typeof t.animateIOSTransition === 'function' && t.animateIOSTransition !== Transition.prototype.animateIOSTransition;
}

Type guard

function isConcreteTransition(t: Transition): boolean {
  return Object.getPrototypeOf(t).constructor !== Transition
    && t.animateIOSTransition !== Transition.prototype.animateIOSTransition;
}

Try / catch

try {
  transition.animateIOSTransition(ctx, from, to, op);
} catch (e) {
  if (String(e.message).includes('Abstract method call')) {
    console.error('Transition subclass does not implement animateIOSTransition');
    transition = new FadeTransition(300);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling transition.animateIOSTransition(...) directly on a base Transition instance or a custom subclass that did not override animateIOSTransition; instantiating Transition itself and passing it to navigation APIs expecting a concrete transition.

Common situations: Writing a custom page transition by extending Transition but only overriding createAndroidAnimator/getCurve; upgrading NativeScript where a previously used helper class no longer overrides this method; copy-pasting a base-class reference instead of a concrete transition (e.g. new Transition() instead of new SlideTransition()).

Related errors


AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30). Data as JSON: /api/errors/8280d8a319301eba. Report an issue: GitHub.