Skip to content

CMI Economy balance change triggers Folia/Canvas thread check when Plan CMI extension handles event #10293

@DimaSergeew

Description

@DimaSergeew

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

  1. Run CMI + CMILib + Plan on CanvasMC/Folia-style server.
  2. Enable CMI economy / Plan CMI extension.
  3. Trigger CMI balance changes, for example with /pay between players or use /baltop while payments are happening.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions