Field Assignment Never Observed

ID

go.field_assignment_never_observed

Severity

high

Remediation Complexity

simple

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

CWE:563, correctness, reliability

Description

Reports an assignment to a field of a method’s value receiver (func (v T) m() { v.field = X }) whose write can never be observed. A value receiver is a copy made only for the duration of the call, so a field stored into it is thrown away when the method returns.

Rationale

Methods declared on a value receiver operate on a copy of the receiver, not on the caller’s value. Storing into a field of that copy has no effect the caller can see, and when nothing in the method reads the receiver again the store is provably dead — almost always a sign the method was meant to take a pointer receiver (func (v *T) m()).

To stay free of false positives the rule fires only when the receiver is a named value receiver, the target is a direct field of that receiver (v.field), and the receiver is never used anywhere after the assignment in the method body. Any later read leaves the write alone.

func (v T) set() {
    v.x = 1 // FLAW — value receiver copy, the field write is discarded at return
}

func (v *T) set() {
    v.x = 1 // OK — pointer receiver, visible to the caller
}

func (v T) set() {
    v.x = 1 // OK — the receiver is read after the write
    println(v.x)
}

Remediation

Change the method to take a pointer receiver (func (v *T) m()) so the field write reaches the caller’s value, or remove the dead assignment if it was unintended.