Introduction Link to heading

If you have 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:

cannot import "main"

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:

go mod init main

That creates the following go.mod file:

module main
go 1.25.3

Then you might have a simple file like this:

package main

func main() {
  square(4)
}

func square(n int) int {
  return n * n
}

Now you decide to write a quick unit test in main_test.go:

package main

import "testing"

func TestSquare(t *testing.T) {
  t.Log("Test successful")
}

At this point, everything looks fine — until you run:

go test

and get the following output:

# main.test
$WORK/b001/_testmain.go:14:8: could not import main (cannot import "main")
FAIL    main [build failed]
FAIL

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:

module myapp
go 1.25.3

Then rerun:

go test

You should now see:

ok   myapp  0.35s

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 main can’t be imported, which breaks that process.
  • Rename your module or move testable code to another package.
  • Reserve main strictly 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.