Introduction Link to heading
If you’ve ever initialized a new Go project with go mod init main and later tried to write tests for it, you may have seen this cryptic error:
Link to heading
cannot import “main”
Link to heading
At first glance, this doesn’t make much sense — after all, your code and tests are both in package main. However, there’s a subtle interaction between how Go handles modules, packages, and test harnesses that causes this issue. Let’s walk through what’s actually happening.
Setting Up the Problem Link to heading
The go.mod File
Link to heading
When you initialize a new Go module for an executable project, it’s common to do something like:
Link to heading
go mod init main
Link to heading
That creates the following go.mod file:
Link to heading
module main go 1.25.3
Link to heading
Then you might have a simple file like this:
Link to heading
package main
func main() { square(4) }
func square(n int) int { return n * n }
Link to heading
Now you decide to write a quick unit test in main_test.go:
Link to heading
package main
import “testing”
func TestSquare(t *testing.T) { t.Log(“Test successful”) }
Link to heading
At this point, everything looks fine — until you run:
Link to heading
go test
Link to heading
and get the following output:
Link to heading
main.test Link to heading
$WORK/b001/_testmain.go:14:8: could not import main (cannot import “main”) FAIL main [build failed] FAIL
Link to heading
Why This Happens Link to heading
When you run go test, the Go toolchain generates a temporary test harness (a _testmain.go file). This harness imports the package under test so that it can invoke your test functions.
Here’s the catch: the test harness must import the module under its module path. When your module path is literally "main", the compiler refuses — because main is reserved for executables and cannot be imported like a normal package.
This only affects go test (and go test .), because those commands rely on the generated import. When you explicitly specify files (e.g., go test *.go), Go skips module resolution and compiles everything together manually, avoiding the import step entirely.
The Fix Link to heading
Option 1: Rename the Module Link to heading
Change your go.mod file to use a different name, for example:
Link to heading
module myapp go 1.25.3
Link to heading
Then rerun:
Link to heading
go test
Link to heading
You should now see:
Link to heading
ok myapp 0.35s
Link to heading
Option 2: Move Testable Code Out of main
Link to heading
In most cases, your main package should be minimal — it should only wire dependencies together. Any functions that need unit tests should live in a separate package (for example, internal/mathutil), which can then be imported both from your main application and from your test files.
Key Takeaways Link to heading
- The Go test harness always imports the package under test.
- A module named
maincan’t be imported, which breaks that process. - Rename your module or move testable code to another package.
- Reserve
mainstrictly for integration and startup logic.
Conclusion Link to heading
This issue isn’t a compiler bug — it’s just an edge case that surfaces when your module path collides with Go’s internal naming conventions.
If you ever see cannot import "main" when testing, remember: rename the module or refactor your code to follow Go’s standard package layout.