Description of issue
On a Canvas/Folia-style server, CMI Economy balance changes repeatedly trigger thread check errors when the Plan CMI extension handles the balance change event.
The stack shows CMI running the economy balance change flow from CMIFoliaImpl.runTaskAsynchronously, then Plan's CMI listener calls CMIUser.getPlayer(), which ends up calling CraftPlayer.loadData() from a Folia async scheduler thread. Canvas rejects this with Cannot load data async.
This happens during normal economy usage such as /pay and /baltop, and fills the console/latest.log with ERROR + WARN stack traces.
Version Information
- CMI:
9.8.7.6
- CMILib:
1.5.9.6
- Plan:
5.7-build-3341
- Server: CanvasMC
26.1.2 build 788 stable (Folia-style region scheduler)
Errors
[Folia Async Scheduler Thread #33/ERROR]: [ca.spottedleaf.moonrise.common.util.TickThread] Thread failed main thread check: Cannot load data async, context=[thread=Thread[#10076,Folia Async Scheduler Thread #33,4,Folia Region Scheduler ThreadGroup],class=java.lang.Thread]
java.lang.Throwable
at ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(TickThread.java:97) ~[canvas-26.1.2.jar:26.1.2-788-00b4aed]
at org.bukkit.craftbukkit.entity.CraftPlayer.loadData(CraftPlayer.java:1384) ~[canvas-26.1.2.jar:26.1.2-788-00b4aed]
at CMI-9.8.7.6.jar//com.Zrips.CMI.NBT.MojangMappings.getPlayer(MojangMappings.java:133) ~[?:?]
at CMI-9.8.7.6.jar//com.Zrips.CMI.Containers.CMIUser.getPlayer(CMIUser.java:414) ~[?:?]
at CMI-9.8.7.6.jar//com.Zrips.CMI.Containers.CMIUser.getPlayer(CMIUser.java:406) ~[?:?]
at Plan-5.7-build-3341.jar//net.playeranalytics.extension.cmi.CMIEventListener.onBalanceChange(CMIEventListener.java:84) ~[?:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[canvas-api-26.1.2.build.788-stable.jar:?]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[canvas-api-26.1.2.build.788-stable.jar:?]
at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:57) ~[canvas-26.1.2.jar:26.1.2-788-00b4aed]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[canvas-26.1.2.jar:26.1.2-788-00b4aed]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[canvas-api-26.1.2.build.788-stable.jar:?]
at CMI-9.8.7.6.jar//com.Zrips.CMI.Modules.Economy.CMIEconomyAcount.lambda$0(CMIEconomyAcount.java:79) ~[?:?]
at CMILib1.5.9.6.jar//net.Zrips.CMILib.Version.Schedulers.CMIFoliaImpl.lambda$runTaskAsynchronously$1(CMIFoliaImpl.java:57) ~[?:?]
at io.papermc.paper.threadedregions.scheduler.FoliaAsyncScheduler$AsyncScheduledTask.run(FoliaAsyncScheduler.java:216) ~[canvas-26.1.2.jar:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) ~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1474) ~[?:?]
A second WARN stack follows immediately with the same root cause:
[Folia Async Scheduler Thread #33/WARN]: java.lang.IllegalStateException: Thread failed main thread check: Cannot load data async
at ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(TickThread.java:98)
at org.bukkit.craftbukkit.entity.CraftPlayer.loadData(CraftPlayer.java:1384)
at CMI-9.8.7.6.jar//com.Zrips.CMI.NBT.MojangMappings.getPlayer(MojangMappings.java:133)
at CMI-9.8.7.6.jar//com.Zrips.CMI.Containers.CMIUser.getPlayer(CMIUser.java:414)
at CMI-9.8.7.6.jar//com.Zrips.CMI.Containers.CMIUser.getPlayer(CMIUser.java:406)
at Plan-5.7-build-3341.jar//net.playeranalytics.extension.cmi.CMIEventListener.onBalanceChange(CMIEventListener.java:84)
at CMI-9.8.7.6.jar//com.Zrips.CMI.Modules.Economy.CMIEconomyAcount.lambda$0(CMIEconomyAcount.java:79)
at CMILib1.5.9.6.jar//net.Zrips.CMILib.Version.Schedulers.CMIFoliaImpl.lambda$runTaskAsynchronously$1(CMIFoliaImpl.java:57)
Reproduction
- Run CMI + CMILib + Plan on CanvasMC/Folia-style server.
- Enable CMI economy / Plan CMI extension.
- Trigger CMI balance changes, for example with
/pay between players or use /baltop while payments are happening.
- Check console/latest.log.
Expected behavior
CMI economy events should not cause Bukkit player data loading from a Folia async scheduler thread. Either the balance change event should be fired/scheduled on a safe player/region context, or the exposed CMI user data used by listeners should be safe to access without calling CraftPlayer.loadData() asynchronously.
Additional context
In the current latest.log, this exact Cannot load data async pattern appeared 42 times, with 168 CMI stack frames and 42 Plan CMI extension frames. Player UUIDs and IPs were redacted from this report.
Description of issue
On a Canvas/Folia-style server, CMI Economy balance changes repeatedly trigger thread check errors when the Plan CMI extension handles the balance change event.
The stack shows CMI running the economy balance change flow from
CMIFoliaImpl.runTaskAsynchronously, then Plan's CMI listener callsCMIUser.getPlayer(), which ends up callingCraftPlayer.loadData()from a Folia async scheduler thread. Canvas rejects this withCannot load data async.This happens during normal economy usage such as
/payand/baltop, and fills the console/latest.log with ERROR + WARN stack traces.Version Information
9.8.7.61.5.9.65.7-build-334126.1.2 build 788 stable(Folia-style region scheduler)Errors
A second WARN stack follows immediately with the same root cause:
Reproduction
/paybetween players or use/baltopwhile payments are happening.Expected behavior
CMI economy events should not cause Bukkit player data loading from a Folia async scheduler thread. Either the balance change event should be fired/scheduled on a safe player/region context, or the exposed CMI user data used by listeners should be safe to access without calling
CraftPlayer.loadData()asynchronously.Additional context
In the current
latest.log, this exactCannot load data asyncpattern appeared 42 times, with 168 CMI stack frames and 42 Plan CMI extension frames. Player UUIDs and IPs were redacted from this report.