End portal teleports player riding a vehicle to world spawn instead of respawn point (Bukkit portal events bypassed in async portal path)
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 4.4k
- Forks
- 623
- PR merge metrics
- No merged PRs in 30d
Description
Expected behavior
When a player rides a vehicle (boat, minecart, mounted animal, etc.) and the vehicle enters an end portal in The End, the player should be returned to their personal respawn location (bed / respawn anchor / Player#setRespawnLocation), matching the behavior of a player walking into the end portal on foot.
At minimum, EntityPortalEvent (or PlayerPortalEvent for the passenger) should be fired so plugins can correct the destination.
Observed/Actual behavior
When a player is a passenger of any non-player vehicle (most easily reproduced with a boat that also carries another mob, since solo riders are dismounted automatically) and that vehicle hits an end portal block in The End:
The whole passenger tree, including the player, is teleported to the overworld world spawn, not the player's respawn location.
Neither EntityPortalEvent nor PlayerPortalEvent is fired for this teleport, so plugins cannot intercept and rewrite the destination.
A player walking into the same portal on foot is correctly returned to their respawn location, so the behavior is inconsistent between "player on foot" and "player as a passenger".
Tracing through NMS, the divergence is in Entity#findOrCreatePortalAsync (Folia region-threading patch). For PortalType.END returning to the overworld it builds the TeleportTransition directly from destination.getRespawnData().pos() and calls portalInfoCompletable.complete(...) without ever going through CraftEventFactory#handlePortalEvents. So the Bukkit event layer that exists on the synchronous vanilla path (EndPortalBlock#getPortalDestination → handlePortalEvents → callEntityPortalEvent / callPlayerPortalEvent) is skipped entirely under region threading.
For the player-on-foot case, vanilla short-circuits inside EndPortalBlock#getPortalDestination with serverPlayer.findRespawnPositionAndUseSpawnBlock(...) before reaching findOrCreatePortalAsync, which is why that path still works correctly.
Steps/models to reproduce
Start a Folia server, join with a single player.
Set the player's respawn location somewhere distinctive in the overworld (sleep in a bed far from world spawn, or use Player#setRespawnLocation from a plugin).
Travel to The End.
Place a boat near the active end portal and have the player board it together with another mob (e.g. a villager, animal, or any second passenger so the boat is not auto-dismounted on portal entry).
Steer the boat onto an end portal block.
Expected: the player is returned to their respawn location.
Actual: the player ends up at the overworld world spawn; the boat (and other passengers) is also at world spawn; no EntityPortalEvent / PlayerPortalEvent is fired during the transit.
The same behavior reproduces with minecarts and any mountable mob (horse, camel, pig) used as the vehicle — anything that prevents the player from being implicitly dismounted before the portal triggers.
Plugin and Datapack List
empty
Folia version
26.1.x.local at commit 9fea7968a62a85e6c0f3d2b86644c117898a0362
Other
No response
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing Entity#findOrCreatePortalAsync with EndPortalBlock#getPortalDestination and CraftEventFactory#handlePortalEvents, tracing the asynchronous end-portal path for passenger trees. Reproduce the boat or minecart case, then verify that the player's respawn location is used and the appropriate EntityPortalEvent or PlayerPortalEvent is fired, matching the walking-player behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100