Go / Gin

Go "Undefined: Package" After Adding New File

When Go reports something as "undefined" right after you add a new file to an existing package, the new file's contents almost always aren't actually part of the package Go thinks it should be — usually because of a package declaration mismatch or a file placed in the wrong directory.

The Problem

You add a new function or type in a new file within an existing package, expecting to use it from other files in the same package, but the compiler reports:

./main.go:10:2: undefined: ValidateUser

The function is clearly defined in the new file, and everything looks syntactically correct, which makes the "undefined" error confusing.

Why It Happens

Go determines what belongs to a package based on the package declaration at the top of each file and the file's location on disk — both need to align correctly for the compiler to treat files as part of the same package. Common causes:

  • The new file has a different package declaration than the other files in the same directory, even by a small typo — Go requires every file in a directory to declare the exact same package name
  • The file was saved in the wrong directory entirely, physically outside the package folder it was meant to belong to
  • The function or type name in the new file starts with a lowercase letter, making it unexported — accessible within the same package, but not if you're trying to use it from a different package that imported this one
  • A stale build cache is causing the compiler to use an outdated cached version of the package that doesn't yet reflect the new file

The Fix

First, confirm the package declaration in the new file exactly matches every other file in the same directory:

// existing file: user.go
package models

// new file: validation.go - must match exactly
package models

A mismatch here, even something subtle like Models versus models, causes Go to treat the file as belonging to a different package entirely, making anything defined in it invisible to the rest of the package.

Confirm the file is physically located in the correct directory. Go determines package membership by directory, not by any explicit "add to project" step — a file saved one level up or down from where it should be simply isn't part of the package you expect:

ls -la ./models/
# confirm validation.go is actually listed here, in the same folder as user.go

If you're trying to use the new function from a different package (not the same one), confirm it's exported — starting with a capital letter — since Go's visibility rules are based entirely on capitalization, with no separate "public/private" keyword:

// Not accessible outside this package
func validateUser(u User) bool { ... }

// Accessible from other packages that import this one
func ValidateUser(u User) bool { ... }

If the declaration and location both look correct but the error persists, clear Go's build cache, since a stale cache occasionally causes exactly this kind of confusing "undefined" error after adding new files:

go clean -cache
go build ./...

Also make sure your editor or IDE has actually saved the new file to disk — some editors show unsaved changes in a way that's easy to miss, and the compiler only sees what's actually written to the filesystem.

Still Not Working?

If you're working inside a monorepo or a project with multiple Go modules, confirm the new file is within the same module as the code trying to use it — a file placed in a directory belonging to a different go.mod is effectively a separate module entirely, and referencing something from it requires a proper import path and module dependency, not just physical proximity in the folder structure:

find . -name "go.mod"

Running this from your project root reveals every module boundary in the repository, which quickly clarifies whether the new file genuinely belongs to the same module as the code that's failing to find it.