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:

  1. The file name and line number (.\hello.go:6). Look there first. Always. A .\ at the front means "in this folder".
  2. The column (18), how far along the line Go noticed the problem, counting characters from the left. A tab counts as one character.
  3. 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:

  1. Run the file.
  2. Read the first error: line number, then column, then message.
  3. Fix that one thing.
  4. 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.