Problem: You're using scheduler, config, database, or placeholders in your script's constructor.
Why: APIs are injected AFTER the constructor runs, so they're null in the constructor.
Solution: Use APIs in event handlers or methods, not constructors.
Bad:
public class MyScript implements Listener {
private ScriptScheduler scheduler;
public MyScript() {
scheduler.runLater(() -> { // scheduler is null here!
// code
}, 100L);
}
}Good:
@FoliaSupport
public class MyScript implements Listener {
private ScriptScheduler scheduler;
// Called immediately after all APIs are injected!
public void onEnable() {
scheduler.runLater(() -> {
// APIs are fully available here
}, 100L);
}
}Problem: Using Bukkit.getScheduler() on Folia server.
Why: Folia doesn't support the old Bukkit scheduler.
Solution: Use JavaSkript's ScriptScheduler instead (auto-injected and works on both Paper and Folia).
Bad:
Bukkit.getScheduler().runTaskLater(plugin, () -> {
// code
}, 100L);Good:
private ScriptScheduler scheduler; // Auto-injected
scheduler.runLater(() -> {
// code
}, 100L);Check:
- Console for compilation errors
- Class is
public - Imports are correct
- No syntax errors
- If using multiple classes, ensure one is public
Run: /js reload <scriptname> to see specific errors
Problem: Helper classes not accessible or not loading.
Solution:
- Ensure only ONE class is
public - Other classes should be package-private (no
publickeyword) - Public class name must match file name
- Check console for "Found X class(es)" message
See Multiple Classes Guide for details.
Check:
- Class name ends with "Command" (e.g.,
HealCommand→/heal) - Implements
CommandExecutor - Console shows "Dynamically registered command: /yourcommand"
Check:
- Field names are exact:
scheduler,config,database,placeholders - Fields are
private(notpublicorstatic) - Not trying to use them in constructor
Problem: Server is using old compiled version of script.
Solution:
- Delete the script file from
plugins/JavaSkript/scripts/ - Restart server (regenerates from resources)
OR
- Run
/js disable <script>to disable it - Edit the script file
- Run
/js enable <script>to reload it
On Folia: Scripts without @FoliaSupport show warnings.
Solution: Add annotation to your script:
import dev.mukulx.javaskript.script.FoliaSupport;
@FoliaSupport
public class MyScript implements Listener {
// Your code
}If Paper-only: Mark it:
import dev.mukulx.javaskript.script.PaperOnly;
@PaperOnly
public class MyScript implements Listener {
// Your code
}Check: /js list shows disabled scripts in red with [Disabled]
Solution: /js enable <script>
Check:
- File watcher is running (console shows "File watcher started")
- Saving the file (not just editing)
- File is in
plugins/JavaSkript/scripts/folder
Manual reload: /js reload <script>
Check:
- Not using
databasein constructor - Table created before using it
- SQL syntax is correct
Example:
@EventHandler
public void onPluginEnable(PluginEnableEvent event) {
if (!event.getPlugin().getName().equals("JavaSkript")) return;
database.createTable("players",
"uuid TEXT PRIMARY KEY",
"name TEXT"
);
}Check:
- Permission registered in
PluginEnableEvent - Permission name is correct
- Player has the permission (check with LuckPerms/etc)
By default, JavaSkript intercepts script exceptions and formats them cleanly in the console, highlighting the exact script line:
[Script Error] pvp/CombatLog.java:42 (in onAttack)
↳ NullPointerException: Cannot invoke "Player.getName()" because "target" is null
If you ever need the full unformatted 60-line Java stack trace for advanced debugging:
- Run
/js debugin-game or console. - Or change the setting in
plugins/JavaSkript/config.yml:errors: clean-stack-traces: false
- Check console for error messages
- Read the error message carefully (they explain the problem!)
- Check example scripts in
plugins/JavaSkript/scripts/ - Read documentation in
docs/folder - Report issues on GitHub with:
- Full error message
- Script code
- Server version (Paper/Folia)
- JavaSkript version