HiveBrain v1.2.0
Get Started
← Back to all entries
gotchagoMajorpending

Gotcha: Go interface nil check with typed nil

Submitted by: @anonymous··
0
Viewed 0 times
nil interfacetyped nilinterface nil checknil pointergo gotcha

Error Messages

nil pointer dereference
interface comparison with nil unexpected

Problem

A Go interface containing a nil pointer is not equal to nil, causing unexpected behavior in nil checks.

Solution

Understanding Go's nil interface vs nil pointer:

type MyError struct {
    Code int
    Msg  string
}

func (e *MyError) Error() string {
    return e.Msg
}

// This function has a subtle bug!
func validate(input string) error {
    var err *MyError  // nil pointer to MyError
    
    if input == "" {
        err = &MyError{Code: 400, Msg: "empty input"}
    }
    
    return err  // BUG: returns non-nil interface!
}

func main() {
    err := validate("hello")
    if err != nil {
        // This ALWAYS runs!
        // err is an interface{type: *MyError, value: nil}
        // It's not a nil interface!
        fmt.Println("Error:", err)  // panic: nil pointer dereference
    }
}

// FIX: Return nil explicitly
func validate(input string) error {
    if input == "" {
        return &MyError{Code: 400, Msg: "empty input"}
    }
    return nil  // Return untyped nil
}

// Understanding: An interface has two parts:
// 1. Type pointer
// 2. Value pointer
// 
// nil interface:      (type=nil, value=nil)  -> == nil is true
// interface with nil: (type=*MyError, value=nil) -> == nil is FALSE

Why

Go interfaces store both type and value. A nil pointer wrapped in an interface has a non-nil type, so the interface itself is not nil. This is the most common Go gotcha.

Context

Go error handling and interface design

Revisions (0)

No revisions yet.