10. Reading error messages
When a program is wrong, Go does not stay silent — it prints an error message and refuses to run the program. Beginners see that text as scary noise and start changing things at random. But it is not noise: Go is telling you exactly which line to look at and hinting at what is wrong. This chapter teaches you to read it.
The shape of an error
Go finds these mistakes while compiling, before any of your program runs. That is why a program with one mistake on its last line prints nothing at all, not even the output of the lines above it.
Almost every Go compile error has the same shape:
# command-line-arguments
file:line:column: message
Three parts, and you read them in this order:
- The file name and line number
(
.\hello.go:6). Look there first. Always. A.\at the front means "in this folder". - The column (
18), how far along the line Go noticed the problem, counting characters from the left. A tab counts as one character. - The message — a short description of what went wrong.
The line # command-line-arguments at the top only says
Go was compiling the file you named. It is not important yet. Go also
does not quote your code, so open the file and go to that line.
Four errors you will actually hit
These four cover most early mistakes. Learn to recognise them by
sight. For each one, imagine this is hello.go in your
go-work folder, run with go run hello.go.
newline in string
You forgot a closing quote.
package main
import "fmt"
func main() {
fmt.Println("hi)
}# command-line-arguments
.\hello.go:6:18: newline in string
.\hello.go:6:18: syntax error: unexpected newline in argument list; possibly missing comma or )
"Newline in string" means Go found an opening quote and
reached the end of the line without finding the closing one. Column 18
is the end of the line, where Go gave up. The second line is a result of
the first, so there is one thing to fix: add the missing "
before the ).
undefined: name
You spelled a name wrong.
package main
import "fmt"
func main() {
fmt.Prinln("hi")
}# command-line-arguments
.\hello.go:6:6: undefined: fmt.Prinln
Go is saying: you used the name fmt.Prinln, but
nothing by that name exists. The name after undefined:
is the misspelled word. Fix: spell fmt.Println.
The same message appears for a name with no fmt. in
front, and then the mistake can cause a second error:
package main
import "fmt"
func main() {
prnt("hi")
}# command-line-arguments
.\hello.go:3:8: "fmt" imported and not used
.\hello.go:6:2: undefined: prnt
Go lists errors in line order, not in order of importance. The real
mistake is on line 6. Once that line says fmt.Println,
fmt is used again and both errors go away.
imported and not used, declared and not used
You brought something into the program and never used it. Many languages let this pass. In Go it is an error. Chapter 08 showed the import version:
package main
import "fmt"
func main() {
// fmt.Println("hi")
}# command-line-arguments
.\hello.go:3:8: "fmt" imported and not used
Variables have the same rule. You meet variables properly in Chapter
11. For now, it is enough to know that name := "Keiko"
below makes a variable, a named box holding the text
Keiko:
package main
import "fmt"
func main() {
name := "Keiko"
fmt.Println("hi")
}# command-line-arguments
.\hello.go:6:2: name declared and not used
Go is saying: you made name and never read it.
Fix: use it, or delete the line. The rule catches real bugs, such as
making a value and then printing the wrong thing.
syntax error: unexpected semicolon or newline before {
You put the opening brace on its own line.
package main
import "fmt"
func main()
{
fmt.Println("hi")
}# command-line-arguments
.\hello.go:6:1: syntax error: unexpected semicolon or newline before {
This one looks odd, since you never typed a semicolon. Go treats the
end of a line such as func main() as the end of a
statement, as if a semicolon were there, so the { on the
next line no longer belongs to it. Fix: move the { up, to
the end of the func main() line.
The edit–run–fix loop
The right way to deal with errors is not to spot them all by eye, but to run a tight loop:
- Run the file.
- Read the first error: line number, then column, then message.
- Fix that one thing.
- Run again.
Repeat until it runs clean. Do not fix three things at once — one "fix" might be wrong, and then you cannot tell which change helped. One error, one fix, run again.
Go can report several errors in one run, and that is fine. Fix the
first and run again, because it may have caused the others. New errors
can also appear after a fix. Go only checks names once the punctuation
of the whole file is correct, so undefined: errors often
show up only after the syntax error: ones are gone. That is
progress, not a step back.
A single mistake sometimes produces a confusing message, or one that
points at the line after the real problem. If the named line
looks fine, check just above it. The brace error above is an example:
the message names the line with the {, and the line break
to remove is at the end of the line above.
The messages in this book were copied from Go 1.22. A newer Go may
word some of them a little differently, but the
file:line:column: message shape is the same, and you read
it the same way.
Open exercises/10/01-three-bugs.go. It does not run. The
first run prints:
# command-line-arguments
exercises\10\01-three-bugs.go:10:1: syntax error: unexpected semicolon or newline before {
exercises\10\01-three-bugs.go:11:25: newline in string
Use the edit–run–fix loop: read the first error, fix only that, run
again. Keep going until it prints All fixed!. There are
three bugs, and the third does not appear until the first two are
gone.
Errors are not failure
Every programmer reads error messages every day. They are not a sign you are bad at this — they are the normal back-and-forth of writing code. Reading errors calmly just means you have read a few thousand of them. You are on your way.
Homework
Homework files are in exercises/10/homework/. Every
starter here fails on purpose until you fix it.
Problem 1 — Name the error
Open exercises/10/homework/01-name-the-error.go. It
contains one broken line. Run it, read the message, and (in a comment at
the bottom) write which of the four errors from this chapter it is. Then
fix it so it greets Keiko.
Problem 2 — Fix the quote
Open exercises/10/homework/02-fix-the-quote.go. It has
an unfinished string. Fix it so the program prints the quote on one
line.
Problem 3 — Fix the typo
Open exercises/10/homework/03-fix-the-typo.go. A
function name is misspelled, giving an undefined: error.
Fix it.
Challenge — Three in a row
Open exercises/10/homework/04-three-in-a-row.go. It has
three separate mistakes, one of each: an opening brace on the wrong
line, an unfinished string, and a misspelled Println. Fix
them one at a time, running after each fix, until the file prints:
Starting up
Working
done
Stuck or finished? Open the homework solutions page.