Skip to content

Fix: Go undefined: variable (or function)

FixDevs ·

Quick Answer

How to fix Go undefined error caused by undeclared variables, wrong package scope, unexported names, missing imports, build tags, and file organization issues.

The Error

You compile a Go program and get:

./main.go:10:5: undefined: myVariable

Or variations:

./main.go:15:2: undefined: MyFunction
./handler.go:8:12: undefined: Config
./main.go:5:2: undefined: fmt

The Go compiler cannot find the variable, function, type, or package you referenced. It either does not exist in the current scope, is in a different package, or is not exported.

Why This Happens

Go resolves names at compile time with strict rules:

  • Variables must be declared before use.
  • Functions and types must be defined in the same package or imported.
  • Names starting with lowercase are unexported (private to the package).
  • Names starting with uppercase are exported (accessible from other packages).
  • Each file must import the packages it uses.

Common causes:

  • Variable not declared. You used a name that was never declared with var, :=, or as a function parameter.
  • Wrong package scope. The name is defined in a different package but not imported or exported.
  • Unexported name. You are trying to use a lowercase name from another package.
  • Missing import. The package is not imported in the current file.
  • File not included in build. Build tags or wrong file naming excludes the file.
  • Typo. The name is misspelled.

Fix 1: Declare the Variable

The simplest case. You used a variable that was never declared:

Broken:

func main() {
    fmt.Println(message)  // undefined: message
}

Fixed:

func main() {
    message := "Hello, World!"
    fmt.Println(message)
}

Or declare at package level:

var message = "Hello, World!"

func main() {
    fmt.Println(message)
}

Go does not have implicit variable creation. Every variable must be explicitly declared with var, :=, or as a function parameter.

Fix 2: Import the Package

If fmt, os, http, or any standard library name is undefined, the package is not imported:

Broken:

func main() {
    fmt.Println("Hello")  // undefined: fmt
}

Fixed:

import "fmt"

func main() {
    fmt.Println("Hello")
}

Multiple imports:

import (
    "fmt"
    "net/http"
    "os"
)

Most Go editors (VS Code with gopls, GoLand) auto-add imports when you save. If auto-import is not working, check your editor’s Go extension settings.

Pro Tip: Use goimports to automatically add and remove imports:

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

Configure your editor to run goimports on save. This eliminates all manual import management.

Fix 3: Export Names with Uppercase

In Go, lowercase names are private to the package. To use a name from another package, it must start with an uppercase letter:

Broken — unexported name:

// config/config.go
package config

var databaseURL = "postgres://localhost/mydb"  // lowercase — unexported
// main.go
package main

import "myapp/config"

func main() {
    fmt.Println(config.databaseURL)  // undefined: config.databaseURL
}

Fixed — export with uppercase:

// config/config.go
package config

var DatabaseURL = "postgres://localhost/mydb"  // Uppercase — exported
// main.go
fmt.Println(config.DatabaseURL)  // Works

This applies to variables, functions, types, constants, and struct fields. If a struct field is lowercase, other packages cannot access it directly.

For similar Go issues with unused variables, see Fix: Go declared and not used.

Fix 4: Fix File Organization in the Same Package

All .go files in the same directory must have the same package name. Functions and types defined in one file are visible in other files of the same package:

myapp/
  main.go      ← package main
  handlers.go  ← package main (same package!)
  utils.go     ← package main (same package!)

Broken — wrong package name:

// handlers.go
package handlers  // Wrong! Must be 'main' if in the same directory as main.go

func HandleRequest() {}

Fixed:

// handlers.go
package main

func HandleRequest() {}

Run all files together:

go run main.go handlers.go utils.go
# Or better:
go run .

If you run only go run main.go, Go does not compile handlers.go, and names defined there are undefined.

Common Mistake: Running go run main.go instead of go run . when your package has multiple files. go run main.go only compiles that single file. go run . compiles all .go files in the current directory with the same package name.

Fix 5: Fix Test File Issues

Names from _test.go files are not available in non-test files:

// helpers_test.go
package main

func testHelper() string {
    return "test"
}
// main.go
package main

func main() {
    testHelper()  // undefined: testHelper (only exists in test files)
}

Test files (_test.go) are compiled only during go test. Move shared helpers to a regular .go file if they are needed outside tests.

External test packages: Files with package main_test are in a different package and can only access exported names:

// math_test.go
package math_test  // External test package

import "myapp/math"

func TestAdd(t *testing.T) {
    result := math.Add(2, 3)  // Must use exported name
}

Fix 6: Fix Build Tags

Build tags can exclude files from compilation. A file with a build tag is only compiled when the tag matches:

//go:build linux

package main

func platformSpecific() {}

This file is only compiled on Linux. On macOS or Windows, platformSpecific is undefined.

Check your build tags:

go build -tags "linux" .

Common build tags:

  • //go:build linux — only on Linux
  • //go:build !windows — everything except Windows
  • //go:build integration — only when -tags integration is specified

If you need a function on all platforms, move it to a file without build tags or create platform-specific implementations:

utils_linux.go    ← //go:build linux
utils_darwin.go   ← //go:build darwin
utils_windows.go  ← //go:build windows

Fix 7: Fix Go Module Issues

If the undefined name is from an external package, the module might not be installed:

go mod tidy

This downloads missing dependencies and removes unused ones.

If the module is not found:

go get github.com/example/package@latest

For Go module resolution errors, see Fix: Go module not found. For “no required module provides package” errors, see Fix: Go no required module provides package.

Fix 8: Fix init() and Package Initialization

init() functions run automatically and cannot be called explicitly:

func init() {
    // Runs automatically when package is loaded
}

func main() {
    init()  // Cannot call init explicitly — but this is a different error
}

If you need initialization logic that can be called manually, use a regular function name like Initialize().

Package-level variables are initialized before init():

var config = loadConfig()  // Runs first

func init() {
    // config is available here
}

func main() {
    // Both config and init() have already run
}

Still Not Working?

If the error persists:

Check for generated code. Some Go projects use code generation (go generate, protobuf, sqlc, ent). Run the generator before building:

go generate ./...
go build .

Check for CGO dependencies. If the code uses import "C" (cgo), you need a C compiler installed. Without it, the cgo file is skipped and names defined there are undefined:

# Install gcc
sudo apt install gcc

# Or disable CGO if not needed
CGO_ENABLED=0 go build .

Check the Go version. Some features (generics, any type, min/max builtins) require a minimum Go version. Check your go.mod:

module myapp

go 1.22

Update if needed:

go install golang.org/dl/go1.22.0@latest

Check for interface embedding issues. If a type is supposed to implement an interface but methods are missing, the compiler might report “undefined” on the method call rather than a clear “does not implement” error.

Use your IDE. VS Code with gopls highlights undefined names immediately and offers “Quick Fix” suggestions. Install the Go extension and ensure gopls is running:

go install golang.org/x/tools/gopls@latest
F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles