---
title: "import cycle not allowed em Go"
url: "https://golang.com.br/erros/import-cycle-not-allowed/"
markdown_url: "https://golang.com.br/erros/import-cycle-not-allowed.MD"
description: "Resolva o erro 'import cycle not allowed' em Go. Aprenda a identificar e quebrar dependências circulares entre pacotes com exemplos práticos."
date: "2026-05-12"
author: "Golang Brasil"
---

# import cycle not allowed em Go

Resolva o erro 'import cycle not allowed' em Go. Aprenda a identificar e quebrar dependências circulares entre pacotes com exemplos práticos.


# import cycle not allowed em Go

O erro **"import cycle not allowed"** acontece quando dois ou mais pacotes dependem um do outro, criando um ciclo de importação. O compilador Go proíbe rigorosamente dependências circulares — se o pacote A importa o pacote B e o pacote B importa o pacote A (diretamente ou por meio de outros pacotes), seu código não compila.

Essa restrição é uma decisão de design que garante compilação rápida e uma arquitetura de dependências clara. Resolver ciclos de importação geralmente resulta em código melhor estruturado.

---

## A Mensagem de Erro

```
package meuapp/handlers
    imports meuapp/models
    imports meuapp/handlers: import cycle not allowed
```

Ou de forma mais indireta:

```
package meuapp/a
    imports meuapp/b
    imports meuapp/c
    imports meuapp/a: import cycle not allowed
```

---

## Causas Comuns

### 1. Dependência Direta Bidirecional

O caso mais óbvio — dois pacotes que dependem um do outro:

```go
// pacote: models/user.go
package models

import "meuapp/handlers" // Importa handlers

type User struct {
    Nome string
}

func (u *User) Handler() handlers.UserHandler {
    return handlers.UserHandler{User: u}
}
```

```go
// pacote: handlers/user_handler.go
package handlers

import "meuapp/models" // Importa models — CICLO!

type UserHandler struct {
    User *models.User
}
```

### 2. Ciclo Indireto (Três ou Mais Pacotes)

Mais difícil de detectar — o ciclo passa por vários pacotes:

```
auth → users → notifications → auth (CICLO!)
```

### 3. Testes Importando Pacote Pai

Pacotes de teste `_test` que importam indiretamente seu próprio pacote:

```go
// pacote: utils/helpers.go
package utils

import "meuapp/service"

func FormatService(s *service.Service) string { ... }
```

```go
// pacote: service/service.go
package service

import "meuapp/utils" // CICLO se utils importa service
```

---

## Como Resolver

### Solução 1: Extrair Interfaces para Pacote Separado

Crie um pacote de "contratos" (interfaces) que outros pacotes implementam:

```go
// pacote: domain/interfaces.go
package domain

// Interface que define o contrato
type UserRepository interface {
    FindByID(id int) (*User, error)
    Save(user *User) error
}

type User struct {
    ID   int
    Nome string
}
```

```go
// pacote: handlers/user_handler.go
package handlers

import "meuapp/domain" // Depende de interfaces, não de implementação

type UserHandler struct {
    repo domain.UserRepository
}

func NewUserHandler(repo domain.UserRepository) *UserHandler {
    return &UserHandler{repo: repo}
}
```

```go
// pacote: repository/postgres.go
package repository

import "meuapp/domain" // Depende do mesmo pacote de interfaces

type PostgresUserRepo struct{}

func (r *PostgresUserRepo) FindByID(id int) (*domain.User, error) {
    // implementação
    return &domain.User{ID: id, Nome: "Alice"}, nil
}

func (r *PostgresUserRepo) Save(user *domain.User) error {
    return nil
}
```

Esse padrão é a base da [clean architecture em Go](/tutoriais/go-clean-architecture/). As [interfaces](/aprenda/golang-interfaces/) permitem desacoplar pacotes sem sacrificar a segurança de tipos.

### Solução 2: Mover Tipos Compartilhados para Pacote Comum

Se dois pacotes compartilham tipos, extraia-os para um terceiro pacote:

```
ANTES (ciclo):
  handlers ←→ models

DEPOIS (sem ciclo):
  domain  ← handlers
  domain  ← models
```

```go
// pacote: domain/types.go
package domain

type User struct {
    ID   int
    Nome string
}

type CreateUserRequest struct {
    Nome  string
    Email string
}
```

### Solução 3: Inversão de Dependência

Ao invés de A depender de B e B depender de A, faça ambos dependerem de uma abstração:

```go
// pacote: notifier/notifier.go
package notifier

// Interface — não depende de ninguém
type UserProvider interface {
    GetEmail(userID int) (string, error)
}

type EmailNotifier struct {
    users UserProvider
}

func New(users UserProvider) *EmailNotifier {
    return &EmailNotifier{users: users}
}

func (n *EmailNotifier) NotifyUser(userID int, msg string) error {
    email, err := n.users.GetEmail(userID)
    if err != nil {
        return err
    }
    // enviar email...
    _ = email
    _ = msg
    return nil
}
```

### Solução 4: Usar Callbacks ou Funções como Parâmetro

Passe comportamento como função ao invés de importar o pacote:

```go
// pacote: processor/processor.go
package processor

// Aceita uma função ao invés de importar o pacote de log
type LogFunc func(msg string)

func Process(data []byte, logFn LogFunc) error {
    logFn("processando dados...")
    // processar...
    logFn("concluído")
    return nil
}
```

### Solução 5: Unificar Pacotes Pequenos

Se dois pacotes são tão acoplados que dependem mutuamente um do outro, talvez eles devessem ser um único pacote:

```
ANTES (ciclo):
  user_model ←→ user_validator

DEPOIS (unificado):
  user (contém model + validator)
```

---

## Ferramentas para Detectar Ciclos

### go list

Visualize as dependências de um pacote:

```bash
# Lista imports diretos
go list -f '{{.Imports}}' ./handlers/

# Lista todas as dependências (transitivas)
go list -f '{{.Deps}}' ./handlers/
```

### Diagrama de Dependências

Use ferramentas como `godepgraph` para visualizar:

```bash
go install github.com/kisielk/godepgraph@latest
godepgraph ./... | dot -Tpng -o deps.png
```

---

## Dicas para Evitar Ciclos de Importação

1. **Planeje a arquitetura de pacotes** — defina camadas claras (domain, service, handler, repository). Veja [clean architecture em Go](/tutoriais/go-clean-architecture/).

2. **Dependa de abstrações** — use [interfaces](/aprenda/golang-interfaces/) para desacoplar pacotes.

3. **Siga o princípio da dependência** — pacotes de nível alto não devem importar pacotes de nível baixo diretamente.

4. **Pacotes pequenos e coesos** — cada pacote deve ter uma responsabilidade clara. Consulte [Go Modules na Prática](/aprenda/go-modules-na-pratica/).

5. **Teste com `go build ./...`** — compile todos os pacotes regularmente para detectar ciclos cedo. Integre ao [CI/CD](/tutoriais/go-tdd-ci-cd/).

Outras linguagens resolvem dependências circulares de formas diferentes: <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a> também proíbe ciclos entre crates, incentivando a mesma separação de responsabilidades que Go exige.

---

## Erros Relacionados

- [undefined: variable or function](/erros/undefined-variable-function/) — pode surgir quando você reestrutura pacotes para resolver ciclos
- [Go Modules na Prática](/aprenda/go-modules-na-pratica/) — organizando dependências corretamente
- [Clean Architecture em Go](/tutoriais/go-clean-architecture/) — padrões de arquitetura que evitam ciclos
- [Microserviços em Go](/tutoriais/go-microservices/) — quando dividir em serviços ao invés de pacotes
