🔧 Error Fixes
· 2 min read
Last updated on

Go: Declared and Not Used — How to Fix It


declared and not used

What causes this

Go treats unused variables as a compile error, not a warning. If you declare a variable and never read from it, the compiler refuses to build. This is a deliberate design decision — the Go team believes unused variables indicate bugs or dead code.

This also applies to unused imports, which produce a separate imported and not used error.

Fix 1: Use the variable

The obvious fix — actually use what you declared:

// ❌ Declared and not used
result, err := doSomething()

// ✅ Use both values
result, err := doSomething()
if err != nil {
    return err
}
fmt.Println(result)

Fix 2: Use the blank identifier

If you genuinely don’t need the value, assign it to _:

// ❌ err is declared but not used
result, err := doSomething()
fmt.Println(result)

// ✅ Discard err explicitly
result, _ := doSomething()
fmt.Println(result)

⚠️ Discarding errors with _ is usually a bad idea in production code. Handle them properly.

Fix 3: Fix unused loop variables

// ❌ index is declared and not used
for index, value := range items {
    fmt.Println(value)
}

// ✅ Use blank identifier for index
for _, value := range items {
    fmt.Println(value)
}

// ✅ Or if you only need the index
for index := range items {
    fmt.Println(index)
}

Fix 4: Fix unused imports

// ❌ imported and not used: "fmt"
import "fmt"

// ✅ Remove the import
// Or use the blank import if you need the side effect
import _ "image/png" // registers PNG decoder

Use goimports to automatically manage imports:

go install golang.org/x/tools/cmd/goimports@latest
goimports -w .

Fix 5: Use a temporary debug trick

During development, you can temporarily suppress the error:

result, err := doSomething()
_ = err     // TODO: handle this
_ = result  // TODO: use this

This makes the compiler happy while you’re still working on the code. Remove these before committing.

Fix 6: Restructure to avoid the variable

// ❌ Unused variable from type assertion
value, ok := data.(string)
// only checking ok, not using value

// ✅ Just check the type without capturing the value
_, ok := data.(string)
if ok {
    // it's a string
}

How to prevent it

  • Configure your editor to run goimports on save — it handles unused imports automatically
  • Use golangci-lint for comprehensive linting beyond what the compiler checks
  • Treat _ = err as a code smell — always handle errors in production code
  • If you’re prototyping, use _ = variable as a temporary placeholder and clean up before committing