Skip to content

Errors ​

Every error Kiln throws is a KilnError with a stable code and a message that reads "what happened. What to do." The CLI prints them as error <code>: <message>, and --json output carries the code. Most of the time the right move is to do what the message says.

ts
import { KilnError } from 'kiln'

try { app.step() } catch (err) {
  if (err instanceof KilnError && err.code === 'not-ready') await app.ready()
}

An exception thrown inside a system that isn't a KilnError is wrapped as system-threw, with the system's name and phase in the message and the original as cause.

The common ones ​

ErrorFix
A and B both take Mut(T) in Fixed with no orderchain(A, B) or B.after(A)
X wrote T.f, but its query takes T read-onlyMut(T) in X's query
X called entity.destroy() during Fixedcommands.despawn(entity)
X wrote Score.value through res.get(Score)res.mut(Score)
X wrote T.f on the copy entity.get() returnsWrite through the row, or entity.set(T, {...}) with Mut(T)
app.step() ran while an async plugin is still loadingawait app.ready() (scenarios do it)
No trait named "X" (kiln run)Check kiln describe; names come from exports
TickTimers and X both take Mut(Timer)X.after(TickTimers)
'x' is not a value of this stateUse one of the listed values, or add it to state([...])
Saves needs the save plugin.use(savePlugin({ resources, traits, persist }))
Ui.click('x'): there is no button 'x'The button isn't set yet (step first) or the id differs
AnimateSprites and X both take Mut(SpriteAnimator)X.before(AnimateSprites) (3D: .before(AnimateModels))
No animation param 'x' / trigger / stateDeclare it in the graph's params / triggers / states
Animation state 's' plays clip 'c', which ... doesn't haveSet the state's clip to one of the listed clips

All codes ​

Schedule ​

CodeWhen
write-conflictTwo systems in one phase take Mut(T) with no order between them
unknown-order-target.after(X) / .before(X) where X isn't in the same phase
cycleOrdering constraints form a cycle (the message prints it)
duplicate-systemA system was added to a phase twice
not-a-phaseapp.add() without a phase first
not-schedulableapp.add() got something that isn't a system, chain or entry
not-a-pluginapp.use() got something that isn't a plugin or function
not-initableapp.init() got something that isn't a resource or event

Access (dev builds) ​

CodeWhen
readonly-writeA system wrote a trait its query takes read-only
undeclared-writeentity.set(T, ...) without Mut(T) in the system's queries
write-to-copyA write to the copy entity.get(T) returns
readonly-resourceA write through res.get(R)
structural-in-systementity.add, entity.remove or entity.destroy inside a system
world-writeA write through the read-only ctx.world
app-in-systemapp.spawn, app.set and friends called inside a system

App lifecycle ​

CodeWhen
not-readyStepping before async plugins finished
disposedUsing an app after dispose()
too-many-appsMore than 16 live apps (dispose the ones you're done with)
headless-renderapp.render() on an app that hasn't started on a canvas
system-threwA system threw a non-Kiln error
pending-entityPendingEntity.get() before commands applied
no-input-pluginapp.input without the input plugin

States, timers, tweens, UI, saves ​

CodeWhen
unknown-state, empty-stateA state value not in the list, or a state with no values
not-an-eventDelayed.emit without an event
tween-args, tween-field, unknown-easeBad Tweens.to arguments
ui-id, ui-anchor, no-buttonBad HUD ids or anchors; clicking a missing button
no-save-plugin, save-slot, save-corruptSaves without the plugin; a bad slot name; unreadable slot data

Assets, rendering, physics ​

CodeWhen
asset-missingA path that isn't in public/
unknown-instancedInstanced(key) with no defineInstanced(key, ...)
physics-not-readyPhysics used before the plugin loaded
no-bodyA Physics call on an entity without a body (bodies appear the step after RigidBody is added)

Animation ​

CodeWhen
graph-empty, graph-param, graph-eventA malformed animationGraph
graph-unknown-state, graph-unknown-param, graph-unknown-triggerThe graph names something it doesn't declare
anim-unknown-state, anim-unknown-param, anim-unknown-triggerAn animator call names something the graph doesn't declare
anim-unknown-clipA state plays a clip the sheet or model doesn't have
anim-frame-eventA frame event on a glTF clip (use { at: seconds })
anim-no-clips, anim-model-failedA 3D animator with nowhere to get clips, or a failed model
sprite-clip, sprite-frame, sprite-grid, sprite-no-sheet, not-a-sheetMalformed sprite sheets and animators

Recordings ​

CodeWhen
not-a-recording, recording-versionThe file isn't a Kiln recording, or is from another version
record-after-boot, replay-after-bootA Recorder or Replayer created after Startup ran
replay-configReplaying on an app with a different loop config
replay-divergedA strict replay's state stopped matching
recorder-stoppedstop() called twice

CLI ​

CodeWhen
no-entry, bad-entrysrc/main.ts missing, or not default-exporting a function that returns the app
unknown-trait, unknown-resource, unknown-eventA name passed to --snapshot, --resources or --events doesn't exist
bad-scriptA malformed input script event
no-recordingkiln replay without a file, or with a missing one
no-chromiumkiln shot can't find a browser
unknown-plugin, plugin-existskiln add with an unknown name, or over an existing folder
missing-dir, not-emptykiln new without a folder, or into a non-empty one