Quick answer: Pass arguments via method.bind(arg). Ensure the callback’s target node remains in the tree until the tween reaches it. Check that the parent node binding the tween is alive.

A tween chain: fade in, wait 1 second, then call on_intro_done. The fade and wait run; the callback never fires. The target object was freed during the wait, killing the tween silently.

Tween Auto-Kill

Tweens created by node.create_tween() are bound to that node. If the node leaves the tree (queue_free, scene change), the tween dies and remaining steps are skipped. Callbacks queued after the death point silently drop.

Fix 1: Bind to a Stable Node

# If self is short-lived, anchor on a longer-lived ancestor
var tween = get_tree().create_tween()
tween.tween_property(self, "modulate:a", 1.0, 0.5)
tween.tween_interval(1.0)
tween.tween_callback(on_intro_done)

get_tree().create_tween() binds the tween to the SceneTree, which lives until program exit. Even if your node is freed, the callback fires (though the callback method may target a freed object).

Fix 2: Check Validity in the Callback

func on_intro_done():
    if not is_instance_valid(self): return
    # body

Defensive: callback runs but skips work if its target object is gone. Combined with tree-bound tween, you get safe long-running tween chains.

Fix 3: bind for Arguments

func spawn_explosion(strength: int):
    # ...

var tween = create_tween()
tween.tween_interval(0.3)
tween.tween_callback(spawn_explosion.bind(5))

bind attaches arguments to the Callable. The tween runs spawn_explosion(5). Without bind, the callable has no args and the method’s strength parameter is missing — producing an error or silent skip depending on Godot version.

Diagnose

Print at each step:

tween.tween_callback(func(): print("step A"))
tween.tween_interval(1.0)
tween.tween_callback(func(): print("step B"))

If step A prints but step B doesn’t, something between killed the tween. Usually a freed node.

Verifying

Build a test sequence with multiple callbacks separated by intervals. All should fire in order. If one skips, check what happens to the tween-binding node between callbacks.

“Tweens die with their host node. Use bind for args; use tree.create_tween or a stable host for long chains.”

For purely visual tween chains (animations on transient sprites), keep tween bound to sprite — the death of the sprite also kills the unneeded animation. Perfect.