Interface Nil Comparison
ID |
go.interface_nil_comparison |
Severity |
low |
Remediation Complexity |
moderate |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
CWE:476, error-handling, reliability |
Description
Detects the typed-nil interface trap: comparing an interface-typed value — in practice an error —
to nil when that value was assigned from a concrete pointer. An interface value holds a
(type, value) pair, so once a concrete pointer is stored in it the interface is non-nil even when the
underlying pointer is nil, and the familiar err != nil guard then unexpectedly evaluates to true.
Rationale
A nil pointer is not the same as a nil interface. Assigning a typed nil pointer into an
error-typed variable boxes it as a non-nil interface carrying the concrete type, so a later
if err != nil branch is taken even though no error really occurred. This silently breaks error
handling and is one of the most common Go correctness pitfalls.
type myErr struct{}
func (e *myErr) Error() string { return "boom" }
func bad() {
var p *myErr = nil
var err error = p // err holds (*myErr, nil) — a non-nil interface
if err != nil { // FLAW — taken even though p is nil
// ...
}
}