How errors behave
The item parser is fail-soft by design: a typo in one field almost never crashes a /reload
or takes the rest of your add-on down with it. It logs a WARN, drops just the bad piece, and keeps
loading. A few cases are fail-hard — they reject the whole definition — and they’re worth
knowing so you don’t ship an item or furniture that silently never appears. This page is the field
guide for reading the log and knowing what each fallback means in-game.
The two outcomes
Section titled “The two outcomes”Every problem the parser hits resolves to one of two things:
| Outcome | What it means | Log level |
|---|---|---|
| Skip-the-piece (fail-soft) | The offending field/entry is dropped; the rest of the item loads. | WARN |
| Skip-the-definition (fail-hard) | The whole file is rejected and the item/furniture never registers. | ERROR |
Read it as a rule of thumb: WARN = something you wrote was ignored; ERROR = the item didn’t load
at all. If an item is missing from the game entirely, search the log for ERROR and that file’s name.
Fail-soft: the tolerances
Section titled “Fail-soft: the tolerances”These all produce a WARN and keep going. ✅ Available
Unknown living-motion → “did you mean…?” suggestion
Section titled “Unknown living-motion → “did you mean…?” suggestion”When a key in animations.living_motions doesn’t resolve to any known motion, the parser doesn’t just
drop it — it runs a Levenshtein fuzzy match (tolerance 3 edits) across the vanilla and TiedUp!
motion names and suggests the closest one:
[DataDrivenItemParser] Unknown motion 'WAKL' in item mymod:wrist_cuffs, skipping. Did you mean 'WALK'?The binding for that motion is dropped; every other motion in the block still loads. If your typo is
more than 3 edits from any real name, you get the same skipping line with no suggestion — that
usually means you invented a motion that doesn’t exist. See the full motion list on
Bones & regions and Animations.
Bad ResourceLocation → skipped
Section titled “Bad ResourceLocation → skipped”Anywhere the parser expects a namespace:path id (slim_model, icon, animations.on_equip /
on_unequip, equip_sound / unequip_sound, a living_motions animation, cloth.mesh /
cloth.texture), a malformed string is logged and that one field is set to null/skipped:
[DataDrivenItemParser] Malformed ResourceLocation 'mymodfoo' for on_equip in item mymod:wrist_cuffs (expected 'namespace:path'), skipping.The parser is strict here on purpose: it rejects noNamespace, :path, mod: (empty path) and a
bare : rather than letting minecraft: be silently assumed. In-game the item still equips — it just
won’t play that sound/animation or won’t show that icon.
Unknown region → skipped individually
Section titled “Unknown region → skipped individually”Each name in regions / blocked_regions is upper-cased and matched against the 14 BodyRegion
values. An unknown one is dropped with a WARN; the others stand:
[DataDrivenItems] In mymod:wrist_cuffs: unknown region 'WRISTS' in 'regions', skippingAbsent animation → vanilla fallback
Section titled “Absent animation → vanilla fallback”If an item has no animations block at all, the field is left null and the item keeps the stock
vanilla animator behaviour — it equips and renders, it just doesn’t pose or override any motion. This
is the normal state for a simple item (the wrist cuffs in Your First Item
ship no animation). No log line; absence is not an error.
Likewise, an unresolvable equip_sound/unequip_sound id falls back to the vanilla leather
equip sound rather than going silent, and unequip_sound falls back to equip_sound if you only set
one. 🖥️ Client / singleplayer only (equip sounds are played locally — see the caveat on
Components / packaging).
Empty {} → EMPTY sentinel
Section titled “Empty {} → EMPTY sentinel”The animations block distinguishes absent from present-but-empty:
- No
animationskey → null → vanilla behaviour (above). "animations": {}→ an internal EMPTY marker. The item is explicitly “animation-aware with no bindings” rather than “never looked at.”
In practice both render the same; the distinction exists so tooling can tell an intentionally-blank block from a forgotten one. There’s no reason to prefer one over the other for a static item.
Other quietly-dropped fields
Section titled “Other quietly-dropped fields”| You wrote | What happens | Why |
|---|---|---|
Unknown components key | WARN, that component ignored, rest of the item loads | typo’d or non-existent component |
Non-object component config (e.g. "lockable": true) | WARN, treated as {} (defaults) | components take an object, not a bare value |
movement_modifier without movement_style | WARN, modifier ignored | the modifier only applies when a style is set |
Unknown movement_style | WARN, ignored (item still equips) | not one of WADDLE/SHUFFLE/HOP/CRAWL |
Legacy animation_bones key | WARN, ignored | dead PlayerAnimator-era key; declare bones per-motion via OVERLAY joints instead |
Bad hex in item tint_channels | WARN, that channel skipped, item loads | item tinting is per-channel fail-soft (contrast furniture, below) |
living_motions OVERLAY with no joints | WARN, that binding skipped | an overlay with no joints would mask nothing |
Fail-hard: the cases that reject the whole definition
Section titled “Fail-hard: the cases that reject the whole definition”These log an ERROR and return nothing — the item or furniture never registers, so it won’t
exist in-game at all. If something is simply missing, this table is where to look.
| Trigger | Log (ERROR) |
|---|---|
type is missing or not exactly tiedup:bondage_item | Skipping …: invalid or missing type '…' |
display_name missing or empty | Skipping …: missing 'display_name' |
model missing or empty | Skipping …: missing 'model' |
model is not a parseable ResourceLocation | Skipping …: invalid model ResourceLocation '…' |
regions missing, empty, or all names invalid | Skipping …: missing or empty 'regions' |
| The whole JSON file fails to parse (syntax error) | Failed to parse JSON …: <message> |
Furniture — bad hex color is fail-hard ⚠️ Partial
Section titled “Furniture — bad hex color is fail-hard ”This is the asymmetry to remember. Where an item tolerates a bad tint_channels hex (skips just that
channel), furniture does not — one invalid hex rejects the entire furniture definition:
[FurnitureParser] Skipping mymod:bondage_cross: tint_channels 'frame' has invalid hex color 'red' (expected '#' followed by 6 hex digits)The furniture validator is strict: a channel value must be a string, # followed by exactly 6 hex
digits (#8B4513). No #, the wrong length, or a non-string value, and the whole piece is dropped.
Furniture is fail-hard on id, display_name, model (same spirit as items — though furniture has no
type discriminator), plus a missing or empty seats array and this hex rule. (Player dye recolouring
is separate and not wired — see Furniture.)
A quick triage flow
Section titled “A quick triage flow”- Item not in the game at all? Search the log for
ERROR+ the file name. It hit a fail-hard case (table above) — most oftentype,display_name,model, or all-invalidregions. - Item exists but a feature is missing (no sound, no pose, missing icon, a region not blocked)?
Search for
WARN+ the item id. A field was dropped fail-soft; fix the line it names. - Reload is clean but the pose is wrong on the body? Equip the item and re-check the log — joint names validate at equip, not reload.
- Unknown-motion
WARNwith a “did you mean…?” Take the suggestion; it’s a Levenshtein match against the real motion names. - A crafting recipe doesn’t load? Pack recipes fail like any vanilla recipe — a recipe whose
result.tiedup_itempoints at an id that doesn’t exist is dropped on load. Check the log for the recipe id, and see Packaging for the recipe format.