import cycle not allowed
Go Programming Language
Severity: ModerateWhat Does This Error Mean?
Go's 'import cycle not allowed' error means two or more packages import each other in a circle. For example, if package A imports package B, and package B imports package A, that is a cycle. Go forbids this because circular imports create an impossible situation — neither package can be built before the other. Fix it by refactoring: move the shared code into a third package that both can import without depending on each other.
Affected Models
- Go 1.0 and later
- All Go versions
- go build, go run, go test
Common Causes
- Package A imports package B, and package B imports package A
- A longer chain: A imports B, B imports C, C imports A
- A main package and a utility package each importing the other
- Moving types or interfaces to the wrong package, creating an accidental dependency loop
- Test files in one package importing another package that imports the first
How to Fix It
-
Read the error message to see which packages form the cycle. For example: 'import cycle not allowed in test: myapp/a → myapp/b → myapp/a'.
The arrow notation shows the path of imports. Find where the circle closes — that is where you need to break it.
-
Identify what each package needs from the other. Usually one package only needs a type or interface defined in the other.
The core question: why does package B need to import package A? Often the answer reveals that a type is in the wrong package.
-
Create a new shared package (commonly named 'types', 'models', or 'common') and move the shared types there.
Both A and B can now import the shared package without either importing the other. The cycle is broken.
-
Consider using interfaces to break the dependency. If B only needs to call one method on A, define an interface in B that A's type satisfies.
This is Go's idiomatic way to decouple packages. B depends on the interface, not on package A directly.
-
Review your overall package structure. If many packages are importing each other, the design may need a larger refactor to separate concerns clearly.
Good Go projects have a clear dependency direction: low-level packages do not import high-level packages.
When to Call a Professional
Import cycles prevent the program from compiling at all. The error message lists the packages in the cycle so you can see exactly where the loop is. This usually requires a small refactor — moving shared types or logic into a new package.
Frequently Asked Questions
Why does Go not allow import cycles when other languages do?
Circular imports complicate the build process and make code harder to understand. Go's designers chose simplicity and clarity: every package's dependencies form a directed acyclic graph (no loops). This makes builds fast, deterministic, and easy to reason about.
Can I use a test file to work around import cycles?
You can use external test packages (files ending in _test.go with package name mypackage_test) to avoid some cycles. But you cannot work around a cycle in regular non-test code with this trick. The real fix is always to restructure the packages.
What is the fastest way to find the cycle in a large project?
Run 'go build ./...' and read the error output — Go lists the full import chain. You can also use 'go mod graph' or the 'godepgraph' tool to visualize the dependency graph. For complex projects, draw out the package dependencies on paper to spot the loop.