Debugging
Everyone writes broken code. The skill is fixing it calmly.
When something goes wrong, Bloom doesn't just say "error." It tries to figure out what you meant and tells you how to fix it. This chapter shows you how to read those messages and the tools Bloom gives you to track down problems.
Reading an Error Message
A Bloom error has up to three parts: what went wrong, a suggestion, and a usage hint. For example, calling a circle with too few arguments produces:
circle expects 3 argument(s) but got 2
Check the arguments: circle(x, y, radius)
You might be missing some arguments
Usage: circle(x, y, radius) - Draw a circle
The first line is the problem. The indented lines are help. Read them top to bottom and the fix is usually obvious.
Typos Get a "Did You Mean?"
Misspell a function or variable and Bloom finds the closest real name for you:
Undefined variable 'circel'
Did you mean 'circle'?
Usage: circle(x, y, radius) - Draw a circle
Try it yourself — this sketch has a typo. Run it, read the suggestion, then fix it:
fn setup() {
size(300, 200)
}
fn draw() {
background(rgb(30, 30, 40))
fill(coral)
circel(150, 100, 40)
}Coming From Another Language?
Bloom recognizes keywords from Python and JavaScript and redirects you to the Bloom way:
functionordef→ usefnvarorconst→ useletelif→ useelse ifnull/None/undefined→ usenil&&/||/!→ useand/or/not
Warnings Before You Even Run
Some code is valid but probably not what you wanted. Bloom scans for these and shows a warning without stopping your sketch — for example using = where you meant ==, calling circle(100, 100) without a radius, or writing print "hi" without parentheses. Treat warnings as a friendly second opinion.
Print Your Way to the Answer
The oldest debugging trick still works best: print a value to see what it actually is. Use print() with a template string (note the { } placeholders) to peek at variables as the sketch runs:
let x = 0
fn setup() {
size(300, 200)
}
fn draw() {
background(rgb(30, 30, 40))
x = x + 1
// Watch the value in the console
print("frame {frame}, x is {x}")
fill(coral)
circle(x % width, 100, 30)
}Watch It Run, One Step at a Time
For trickier bugs, you can slow everything down. The How Bloom Works explorer includes a live debugger that re-runs your program and records a snapshot at every statement — which line ran and what every variable held at that moment. Step forward through a loop and watch the counter and your values change in real time.
This is the same step/pause machinery the playground's controls use, driven by the runtime's step() method. If you want to know how pausing mid-execution works under the hood, see the runtime internals.
A Debugging Checklist
- Read the whole message. The fix is usually in the indented hint, not the first line.
- Check the line number. Every error remembers exactly where it came from.
- Print the suspect value. Is it the type and number you expected?
- Comment out half. Narrow down which part of the code causes the problem.
- Step through it. Use the explorer's debugger when the logic, not the syntax, is wrong.
src/lang/errors.ts. The error system deep dive walks through the actual code that produces them.