Troubleshooting
This page is organized by what you see when a test fails. Identify the failure category first, then decide whether to change the test, change the datapack, or keep the issue as a warning.
Quick Diagnosis
| Symptom | Likely cause | Start here |
|---|---|---|
| Build fails with Java or classfile errors | JDK/toolchain mismatch | Getting Started |
pack_format ... expected ... | version profile and pack metadata disagree | Format mismatches |
| Command has no effect | unsupported behavior, low behavior level, or selector mismatch | Command Support |
| Output assertion fails even though the command ran | matching text instead of rawText, or wrong target/channel | Testing Patterns |
| score/storage value is wrong | setup mixed with behavior, or the function was not called | trace + snapshot diff |
| player event does not trigger | incomplete player fixture, context mismatch, or advancement conditions not met | Player Events |
| manifest resource loading fails | invalid path, namespace, JSON/SNBT, or schema | Resource Formats |
Keep the Report First
When debugging, do not call requirePassed() immediately:
val report = SandboxQuickTest.singleFunctionText(source, version = "26.2")
.function()
.assertScore("#unit", "runs", 1)
.report()
report.failures.forEach(::println)
report.outputs.forEach { println("${it.channel}: ${it.rawText}") }
report.traces.forEach { println("${it.root}: ${it.success}") }
report.snapshotDiffs.forEach { println(it.render()) }2
3
4
5
6
7
8
9
This lets you inspect failed assertions, output events, traces, and snapshot diffs. Switch back to requirePassed() once the test is stable.
pack_format and Version Profiles
Typical message:
Datapack format pack_format 100 or range 100..100 is not compatible with version 26.2; expected 107.1Handle it in this order:
- Confirm that
version = "26.2"is the Minecraft version you intended to model. - Check
pack.mcmetaforpack_formatorsupported_formats. - If this is temporary compatibility testing, keep it as a warning and continue validating command/resource behavior.
- If the pack targets that version for release, update pack metadata.
min_format and max_format may be arrays:
{
"supported_formats": {
"min_inclusive": [104, 1],
"max_inclusive": [107, 1]
}
}2
3
4
5
6
The array [104, 1] means 104.1, and [94] means 94.
Command Support Problems
Separate three cases:
| Case | How to debug |
|---|---|
| parse failure | check command syntax and version profile |
| parse succeeds but behavior is no-op | check the command matrix behavior level |
| behavior runs but result is wrong | add assertTrace and snapshot diff |
Temporary trace assertion:
.assertTrace(
root = CommandRoot.EXECUTE,
success = true,
)2
3
4
If trace records execution but the snapshot does not change, the command path was reached but that side effect may not be modeled by the runtime yet.
Output Assertion Failures
Common mistake with chat commands:
// Fragile: rendered chat line
.assertOutput(text = "Hello Minecraft world !")
// Usually better: message passed to say
.assertOutput(rawText = "Hello Minecraft world !")2
3
4
5
Also check:
channel, such asOutputChannel.CHAT,TITLE, orWARNING;targetortargetsafter selector resolution;- whether you need
contains,rawContains, or a regex instead of exact equality.
Selector Did Not Match
When execute as @a or tell @p has no effect, first confirm that the fixture has a player:
.world {
player(
name = "Steve",
x = 0.0,
y = 64.0,
z = 0.0,
)
}
.assertPlayer("Steve", exists = true)2
3
4
5
6
7
8
9
If the selector depends on dimension, tag, distance, predicate, or gamemode, add those fields to the fixture. Do not assume default sandbox player state is identical to a real server.
Resource Path Errors
Datapack resource path errors usually happen before command behavior. Check in this order:
pack.mcmetaexists;- namespace is under
data/<namespace>/...; - functions use
.mcfunction; - JSON matches the resource type;
- SNBT paths stay within the supported subset;
- manifest references use namespaced IDs.
If you test generated output, keep the generated directory when the test fails. The assertion error alone may not be enough.
When to Use Snapshot Diff
Use snapshot diff when you do not know what state changed:
.assertSnapshotDiff(
path = "/scoreboard/scores/#unit/runs",
kind = SnapshotDiffKind.CHANGED,
)2
3
4
Diffs are useful when:
- a command ran but wrote to a different key;
- initial state differs from your assumption;
- multiple functions modify the same storage;
- version profiles change loaded resources.
Tighten Assertions Last
During debugging, use contains, range, and existence assertions. Once stable, switch to exact values.
| Debugging | Stable test |
|---|---|
assertOutput(rawContains = "...") | assertOutput(rawText = "...") |
assertScoreAtLeast(...) | assertScore(...) |
assertEntityCountAtLeast(...) | assertEntityCount(...) |
report() | requirePassed() |