Skip to content

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.

Every problem the parser hits resolves to one of two things:

OutcomeWhat it meansLog 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.

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.

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.

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', skipping

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).

The animations block distinguishes absent from present-but-empty:

  • No animations key → 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.

You wroteWhat happensWhy
Unknown components keyWARN, that component ignored, rest of the item loadstypo’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_styleWARN, modifier ignoredthe modifier only applies when a style is set
Unknown movement_styleWARN, ignored (item still equips)not one of WADDLE/SHUFFLE/HOP/CRAWL
Legacy animation_bones keyWARN, ignoreddead PlayerAnimator-era key; declare bones per-motion via OVERLAY joints instead
Bad hex in item tint_channelsWARN, that channel skipped, item loadsitem tinting is per-channel fail-soft (contrast furniture, below)
living_motions OVERLAY with no jointsWARN, that binding skippedan 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.

TriggerLog (ERROR)
type is missing or not exactly tiedup:bondage_itemSkipping …: invalid or missing type '…'
display_name missing or emptySkipping …: missing 'display_name'
model missing or emptySkipping …: missing 'model'
model is not a parseable ResourceLocationSkipping …: invalid model ResourceLocation '…'
regions missing, empty, or all names invalidSkipping …: 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.)

  1. Item not in the game at all? Search the log for ERROR + the file name. It hit a fail-hard case (table above) — most often type, display_name, model, or all-invalid regions.
  2. 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.
  3. 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.
  4. Unknown-motion WARN with a “did you mean…?” Take the suggestion; it’s a Levenshtein match against the real motion names.
  5. A crafting recipe doesn’t load? Pack recipes fail like any vanilla recipe — a recipe whose result.tiedup_item points 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.