Docs menu

E081: That value might be null when you use it

What compiler error E081 means, and how to fix it.

A reference written &?Box means “a Box, or nothing”. The ? is Turf’s way of making you deal with “nothing” before it can crash your program: you may only read a field of a &?Box where Turf can prove it isn’t null.

Example
struct Box { val: int }fn bad(b: &?Box): int {    return b.val;            // b might be null here}

Check first, and use the value only inside the check:

Example
fn good(b: &?Box): int {    if b != null {        return b.val;        // here Turf knows b is not null    }    return 0;}

The proof only lasts as far as the check does: if the variable is changed in between, or the check was in a different branch, Turf asks again. A loop that does not assign the variable keeps the proof, inside it and after it.

Calling a method counts as a use, exactly like reading a field: b.grow() needs the same check.

A deferred use happens when the block ends, not where it is written: defer io::printline(b.val); followed later in the same block by b = b.next; is rejected, because b may be null by the time the deferred line runs.

The check works on a variable, and only on a variable. A &?Box you got from somewhere else (a field, a call, a list element) has to be put in one first:

Example
struct Node { val: int, next: &?Node }fn bad(n: &Node): int {    return n.next.val;       // n.next might be null, and no check can be written around it}fn good(n: &Node): int {    mut r: &?Node = n.next;    if r != null {        return r.val;    }    return 0;}

If a value can never be null, say so in its type: &Box (no ?) needs no check at all.

Run turf --explain E081 in a terminal to read this again.

Last updated: Oct 15, 2026Edit this page on GitHub

Esc

Type to search.