Understanding the Error

The undefined variable error occurs during compilation:

bash
./main.go:10:5: undefined: myVariable
./main.go:15:8: undefined: someFunction

This error means Go cannot find a declaration for the name you're using. Unlike some languages, Go doesn't allow using undeclared variables.

Common Causes and Solutions

Cause 1: Variable Not Declared

Problem code: ``go func main() { count = 10 // Error: undefined: count fmt.Println(count) }

Solution - Declare the variable: ``go func main() { var count int = 10 // or count := 10 // Short declaration fmt.Println(count) }

Cause 2: Variable Outside Scope

Problem code: ``go func main() { if true { inner := "hello" } fmt.Println(inner) // Error: undefined: inner }

Solution - Adjust scope: ```go func main() { var inner string if true { inner = "hello" } fmt.Println(inner) // Works }

// Or if you need the value outside func main() { inner := "" if true { inner = "hello" } fmt.Println(inner) } ```

Cause 3: Typo in Variable Name

Problem code: ``go func main() { userName := "Alice" fmt.Println(username) // Error: undefined: username (case mismatch) }

Solution - Fix the typo: ``go func main() { userName := "Alice" fmt.Println(userName) // Correct }

Cause 4: Package-level Variable Not Exported

Problem code: ```go // config/config.go package config

var defaultPort = 8080 // Lowercase = unexported

// main.go package main

import "myapp/config"

func main() { fmt.Println(config.defaultPort) // Error: undefined } ```

Solution 1 - Export the variable: ```go // config/config.go package config

var DefaultPort = 8080 // Uppercase = exported

// main.go package main

import "myapp/config"

func main() { fmt.Println(config.DefaultPort) // Works } ```

Solution 2 - Provide a getter function: ```go // config/config.go package config

var defaultPort = 8080

func GetDefaultPort() int { return defaultPort }

// main.go package main

func main() { fmt.Println(config.GetDefaultPort()) } ```

Cause 5: Variable in Different Package

Problem code: ```go // user/user.go package user

type User struct { Name string }

// main.go package main

func main() { u := User{Name: "Alice"} // Error: undefined: User } ```

Solution - Import the package: ```go package main

import "myapp/user"

func main() { u := user.User{Name: "Alice"} fmt.Println(u.Name) } ```

Cause 6: Short Declaration Outside Function

Problem code: ```go package main

count := 10 // Error: syntax error: non-declaration statement outside function body

func main() { fmt.Println(count) } ```

Solution - Use var at package level: ```go package main

var count = 10 // Package-level declaration must use 'var'

func main() { fmt.Println(count) } ```

Cause 7: Assignment Instead of Declaration

Problem code: ``go func main() { var name string name := "Alice" // Error: no new variables on left side of := }

Solution - Use assignment: ``go func main() { var name string name = "Alice" // Assignment, not declaration }

Cause 8: Cyclic Import

Problem code: ```go // package a/a.go package a import "myapp/b" var A = "hello"

// package b/b.go package b import "myapp/a" var B = a.A // Error: undefined during compilation ```

Solution - Restructure packages: ```go // package common/common.go package common var SharedValue = "hello"

// package a/a.go package a import "myapp/common" var A = common.SharedValue

// package b/b.go package b import "myapp/common" var B = common.SharedValue ```

Quick Diagnosis Commands

Check for Typos

```bash # Use go vet to find issues go vet ./...

# Use staticcheck for deeper analysis go install honnef.co/go/tools/cmd/staticcheck@latest staticcheck ./... ```

IDE Assistance

Most Go IDEs highlight undefined variables. Use:

bash
# gopls (Language Server) diagnostics
go install golang.org/x/tools/gopls@latest
gopls check main.go

Module Issues

Sometimes the error is due to missing module:

```bash # Ensure dependencies are downloaded go mod tidy go mod download

# Check imports go list -m all ```

Common Patterns to Avoid

Shadowing Variables

go
func main() {
    name := "outer"
    if true {
        name := "inner" // New variable, shadows outer!
        fmt.Println(name) // "inner"
    }
    fmt.Println(name) // "outer"
}

This is legal but confusing. Use different names:

go
func main() {
    name := "outer"
    if true {
        innerName := "inner"
        fmt.Println(innerName)
    }
    fmt.Println(name)
}

Unused Import

go
import (
    "fmt"
    "os" // Error: imported and not used
)

Either use or remove:

```go import ( "fmt" )

// Or use blank import for side effects import ( _ "github.com/lib/pq" // Driver registers itself ) ```

Verification

After fixing, verify with:

```bash # Compile check go build ./...

# Run tests go test ./...

# Format code go fmt ./... ```