Go "import cycle not allowed" - Fix Circular Imports in CI
Go forbids circular imports between packages. When package A imports B and B imports A (directly or through a chain), the compiler cannot order their initialization and reports import cycle not allowed.
What this error means
A build fails with import cycle not allowed, printing the chain of packages that form the loop. It is deterministic and typically appears right after a refactor that made two packages depend on each other.
package github.com/org/app/service
imports github.com/org/app/store
imports github.com/org/app/service: import cycle not allowedCommon causes
Two packages depend on each other
A new reference made package A import B while B already imported A, forming a cycle the compiler rejects.
Shared types living in the wrong package
Types or helpers used by both packages sit inside one of them, forcing a back-import instead of being in a neutral package both can depend on.
How to fix it
Extract shared code into a third package
Move the types or functions both packages need into a neutral package that neither imports back.
- Identify the symbol that creates the back-edge in the cycle.
- Move it to a new lower-level package (e.g.
internal/model). - Have both original packages import the new one instead of each other.
Invert the dependency with an interface
Define an interface in the lower-level package and have the higher-level one satisfy it, so the dependency points one way.
Locate the cycle
go list -deps ./... > /dev/null # prints the cycle path on failure
go build ./...How to prevent it
- Keep a clear dependency direction (low-level packages never import high-level ones).
- Put shared types in a neutral package both sides can import.
- Use interfaces to invert dependencies instead of back-importing.