Rust panic na inicialização do dev server#
Ambiente: Next.js 16.0.0, Turbopack habilitado, pnpm (versões 8.x ou 9.x recomendadas) como gerenciador de pacotes, Linux. Pré-requisitos do Node.js: O Next.js 16 requer Node.js 18.17+ (sendo altamente recomendado o uso de Node.js 20 LTS). Verifique o seu ambiente executando:
node --version
pnpm --version
Comando de inicialização:
NODE_OPTIONS='--max-old-space-size=4096' next dev -H 0.0.0.0
O servidor de desenvolvimento abortou durante a fase de bundling inicial com o seguinte output fatal no stderr:
thread 'tokio-runtime-worker' (862) panicked at
/build/turbopack/crates/turbo-tasks-backend/src/backend/operation/aggregation_update.rs:1420:17:
inner_of_uppers_lost_follower is not able to remove follower TaskId 17
(ProjectContainer::entrypoints) from TaskId 16 (EntrypointsOperation::new)
as they don't exist as upper or follower edges
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error [TurbopackInternalError]: inner_of_uppers_lost_follower is not able to
remove follower TaskId 17 (ProjectContainer::entrypoints) from TaskId 16
(EntrypointsOperation::new) as they don't exist as upper or follower edges
at Object.resolveEntrypoints ...
at async DevServer.prepare ...
O erro não partiu do código da aplicação: nenhum arquivo .ts, .tsx ou .js do projeto foi mencionado como origem. O panic ocorreu dentro do próprio runtime do Turbopack, em código Rust.
Anatomia do panic: o que o erro realmente diz#
Decodificando a stack trace#
O Turbopack é escrito em Rust e usa um sistema de incremental computation chamado turbo-tasks. Este sistema mantém um grafo de dependências direcionado onde cada nó representa uma "task", a unidade de trabalho que pode ser uma operação de compilação de arquivo, resolução de imports, geração de output de bundle, etc.
O modelo de dados do grafo é o seguinte:
Uma "follower edge" significa: "quando TaskId 17 (entrypoints do projeto) completar, notifique TaskId 16 (operação de entrypoints)". Esta é a mecânica de propagação de invalidação que torna o HMR tão rápido no Turbopack.
O que "inner_of_uppers_lost_follower" significa#
A função inner_of_uppers_lost_follower em aggregation_update.rs:1420 é parte do algoritmo de agregação de dependências, responsável por consolidar e propagar atualizações através do grafo quando um arquivo muda.
O panic ocorre na linha:
// aggregation_update.rs:1420
assert!(
inner_task.followers.remove(&upper_task_id),
"inner_of_uppers_lost_follower is not able to remove follower TaskId {} ({:?}) \
from TaskId {} ({:?}) as they don't exist as upper or follower edges",
upper_task_id, ..., inner_task_id, ...
);
Tradução operacional: O engine Turbopack tentou remover uma borda de dependência entre dois nós do grafo (TaskId 17 → TaskId 16), mas essa borda não existia no estado atual do grafo. A invariante interna foi violada - o grafo está em estado inconsistente - e o Rust, que não faz "silent failures" em assertions, causou um panic.
Por que o estado fica inconsistente?#
Corrupções no turbo-tasks-backend ocorrem principalmente em dois cenários:
- Cache residual de versão anterior: A pasta
.nextcontém serialização do estado do grafo de uma versão diferente do Turbopack. Ao atualizar o Next.js ou o pnpm e reusar o cache antigo, o grafo desserializado pode ter referências a TaskIds que não existem mais na versão nova.
- Bug de concorrência no
tokio-runtime-worker: Múltiplos threads do runtime async do Rust (tokio) operando no grafo simultaneamente podem, em condições de race condition, produzir estado inconsistente. O prefixothread 'tokio-runtime-worker' (862)no panic indica que o erro ocorreu em um worker thread do pool de threads async.
Solução 1 - reset do cache do turbopack (recomendada)#
1.1 verificação de cache corrompido#
Antes de prosseguir com a limpeza agressiva, você pode verificar se o cache do Next.js está presente, o tamanho que ocupa em disco e se existem travas de processo ativas que possam estar impedindo a invalidação automática do Turbopack:
# Verificar se há diretórios de cache estruturados
ls -la .next/cache/
# Analisar o espaço em disco ocupado pelo cache
du -sh .next/cache/
# Checar se existem arquivos de trava residuais
ls -la .next/cache/*.lock 2>/dev/null
# Confirmar se há processos fantasmas do Turbopack rodando em segundo plano
ps aux | grep -i turbopack
1.2 limpeza segura via next clean#
A remoção direta via rm -rf é eficaz, mas o Next.js disponibiliza um comando oficial chamado next clean. O next clean é preferível porque ele remove estritamente os artefatos de build gerados pelo framework (evitando apagar acidentalmente arquivos customizados que o desenvolvedor possa ter colocado manualmente na pasta .next):
# Opção oficial usando npx
npx next clean
# Caso use pnpm
pnpm next clean
1.3 remoção física multi-plataforma#
Caso precise deletar a pasta fisicamente por completo, execute o comando correspondente ao seu sistema operacional:
# Linux e macOS
rm -rf .next
# Windows (PowerShell com privilégios de Admin)
Remove-Item -Recurse -Force .next
# Windows (Command Prompt - CMD)
rmdir /s /q .next
# Alternativa Unix segura sem remover a pasta raiz
find .next -type f -delete && find .next -type d -empty -delete
O que este procedimento remove:
.next/cache/- cache de módulos compilados e grafo de dependências serializado do Turbopack..next/static/- assets estáticos compilados para renderização no cliente..next/server/- bundles de renderização no lado do servidor (SSR)..next/trace- dados estruturados de telemetria de build.
Após a remoção, o Turbopack reconstrói o grafo de computação do zero:
NODE_OPTIONS='--max-old-space-size=4096' pnpm dev
Verificando a resolução: O dev server deve iniciar e compilar as rotas iniciais sem disparar logs de TurbopackInternalError. Output esperado de sucesso:
▲ Next.js 16.0.0 (Turbopack)
- Local: http://localhost:3000
- Network: http://0.0.0.0:3000
✓ Starting...
✓ Ready in 2.4s
1.4 compatibilidade do pnpm#
O Next.js 16 recomenda a utilização de versões recentes do gerenciador pnpm (série 8.x ou 9.x). Verifique se o seu gerenciador atende a esses requisitos ou atualize-o para evitar incompatibilidades de resolução de dependências recursivas:
# Checar versão atual
pnpm --version
# Atualizar globalmente para a versão estável 9.x
npm install -g pnpm@9
1.5 prevenção de cache em Docker e CI/CD#
Em pipelines automatizados de Integração Contínua e na geração de imagens Docker, caches antigos persistidos de builds locais ou passadas são as maiores fontes de panics e falhas de compilação.
Dockerfile (Hardening de Build):
# Antes de rodar a instalação e o build de produção, garanta a limpeza
RUN rm -rf .next || true
# Ou utilize a CLI oficial
RUN npx next clean || true
RUN pnpm build
GitHub Actions Workflow (ci.yml):
# Passo explícito para invalidar caches anteriores do Next.js
- name: Clean Next.js cache
run: rm -rf .next || npx next clean
- name: Start build
run: pnpm build
1.6 interferência de ides e file watchers#
IDEs como VS Code ou a suite JetBrains (IntelliJ, WebStorm) ativam monitoradores de arquivos (file watchers) e servidores de linguagem TypeScript recursivos. Se esses watchers indexarem a pasta .next enquanto o dev server do Turbopack estiver gravando no cache, pode ocorrer conflito de I/O bloqueante (locks de arquivo), gerando o panic.
Solução: Exclua a pasta .next da indexação do VS Code adicionando a seguinte configuração em .vscode/settings.json:
{
"files.watcherExclude": {
"**/.next/**": true,
"**/node_modules/**": true
}
}
Por que o cache do next.js fica corrompido?#
# Causas comuns que produzem o panic pós-reinstalação:
pnpm update next → Nova versão do Turbopack com schema de cache diferente
rm -rf node_modules && bun install → Muda o runtime, grafo serializado incompatível
git pull (com mudanças em tsconfig.json, next.config.js) → Invalidação incompleta
Para prevenir recorrências de desenvolvimento, adicione scripts robustos no package.json:
{
"scripts": {
"dev": "next dev --turbo",
"clean": "next clean",
"dev:clean": "next clean && next dev --turbo",
"build:clean": "next clean && next build"
}
}
Solução 2 - fallback para webpack (continuidade de desenvolvimento)#
Se o panic persistir após múltiplas limpezas de cache (o que indica um bug específico da versão), a saída imediata é remover o Turbopack da equation:
package.json - antes:
{
"scripts": {
"dev": "next dev --turbo"
}
}
package.json - depois:
{
"scripts": {
"dev": "next dev"
}
}
Ou, se o Turbopack foi habilitado via next.config.js:
// next.config.js - ANTES (Turbopack ativo)
const nextConfig = {
experimental: {
turbo: {
rules: { /* ... */ }
}
}
}
// next.config.js - DEPOIS (Webpack como padrão)
const nextConfig = {
// experimental.turbo removido
}
Trade-offs do fallback:
| Aspecto | Turbopack | Webpack fallback |
|---|---|---|
| HMR latência | ~150ms | ~800ms - 2.4s |
| RAM em idle | ~1.3 GB | ~2.8 GB |
| Estabilidade em major release | ⚠️ Bugs esperados inicialmente | ✅ Mais estável |
| Acesso a features Next.js 16 | ✅ Total | ✅ Total |
O fallback para Webpack não perde nenhuma feature do Next.js 16: ele apenas usa o compilador mais antigo. O desenvolvimento continua normalmente enquanto o team da Vercel patcha o bug.
Solução 3 - atualização para versão canary#
Se o panic for um bug já identificado e corrigido nos nightly builds do Next.js, o caminho mais rápido para ter o Turbopack estável é a versão canary:
# Com pnpm
pnpm update next@canary react@canary react-dom@canary
# Com bun
bun update next@canary react@canary react-dom@canary
Verificando a versão canary instalada:
pnpm list next
# └─ next 16.0.1-canary.15 (ou superior)
Quando usar o canary vs. aguardar o stable:
| Critério | Canary | Aguardar Stable |
|---|---|---|
| Projeto em MVP / desenvolvimento | ✅ Aceitável | ✅ Seguro |
| Projeto em produção | ❌ Arriscado | ✅ Obrigatório |
| Erro de build crítico bloqueante | ✅ Testar canary | - |
| Time com capacidade de debug | ✅ Canary útil | - |
Monitorando o repositório do Next.js para o patch:
# Buscar issues relacionados no GitHub CLI (se instalado)
gh issue list --repo vercel/next.js --search "inner_of_uppers_lost_follower"
# Ou acompanhar o CHANGELOG da versão canary
curl -s https://raw.githubusercontent.com/vercel/next.js/canary/packages/next/CHANGELOG.md | grep -A 5 "turbopack"
3.1 reportando e criando uma issue no GitHub#
Caso o panic persista e nenhuma issue correspondente seja encontrada, é essencial reportar o bug fornecendo as informações corretas de diagnóstico para o time do Next.js. Você pode abrir a issue via browser ou diretamente pelo GitHub CLI:
# Criar issue detalhada via GitHub CLI usando metadados do ambiente
gh issue create --repo vercel/next.js \
--title "Turbopack panic: inner_of_uppers_lost_follower in Next.js 16" \
--body "## Ambiente de Execução
- Next.js: \$(pnpm list next 2>/dev/null | grep next | awk '{print \$2}' || echo '16.0.0')
- Node.js: \$(node --version)
- SO: \$(uname -a)
- pnpm: \$(pnpm --version)
## Stack trace de panic do Rust
\`\`\`
\$(cat /tmp/turbopack-panic.log 2>/dev/null || echo 'thread tokio-runtime-worker panicked at inner_of_uppers_lost_follower')
\`\`\`
## Passos para reproduzir
1. Habilitar o modo experimental do Turbopack (\`--turbo\`) no Next.js 16.
2. Executar o dev server com \`pnpm dev\`.
3. Alterar dependências ou atualizar imports de entrypoints rapidamente durante o HMR."
# Ou abrir o fluxo diretamente na interface web do repositório
gh issue create --repo vercel/next.js --web
Habilitando o backtrace e monitoramento avançado#
6.1 backtrace do Rust#
Se você precisa reportar o bug para o repositório oficial do Next.js ou entender a origem exata da quebra lógica, a variável de ambiente RUST_BACKTRACE=1 revela a stack trace completa interna do Rust:
RUST_BACKTRACE=1 NODE_OPTIONS='--max-old-space-size=4096' pnpm dev 2>&1 | tee /tmp/turbopack-panic.log
A saída estruturada resultante trará todos os frames de chamada Rust:
stack backtrace:
0: rust_begin_unwind
at /rustc/.../library/std/src/panicking.rs:647:5
1: core::panicking::panic_fmt
at /rustc/.../library/core/src/panicking.rs:72:14
2: turbo_tasks_backend::backend::operation::aggregation_update::inner_of_uppers_lost_follower
at /build/turbopack/crates/turbo-tasks-backend/src/backend/operation/aggregation_update.rs:1420:17
3: turbo_tasks_backend::backend::operation::aggregation_update::AggregationUpdateQueue::process
at .../aggregation_update.rs:890:13
4: turbo_tasks_backend::backend::TurboTasksBackend::run_backend_job
at .../mod.rs:421:9
...
6.2 monitoramento de consumo de memória#
Estouros de recursos durante a transpilação e watch do Turbopack podem ser identificados por meio do monitoramento da memória RAM. Utilize os seguintes comandos para isolar processos Node.js:
# Listar processos Node.js ativos com porcentagem de CPU/Memória e tamanho em KB
ps aux | grep node | awk '{print "PID: "$2" | CPU: "$3"% | RAM: "$4"% ("$6" KB) | Comando: "$11}'
# Monitorar em tempo real os subprocessos associados ao Next.js
htop -p $(pgrep -f "next dev" | paste -sd,)
# Ativar console de inspeção do Node para análise de perfil de heap
NODE_OPTIONS='--max-old-space-size=4096 --inspect' pnpm dev
6.3 script de diagnóstico completo (diagnose-turbopack.sh)#
Para facilitar a triagem de problemas de ambiente em servidores locais ou containers, crie um script local diagnose-turbopack.sh:
#!/bin/bash
# diagnose-turbopack.sh - Diagnóstico de dependências e cache do Turbopack
set -euo pipefail
echo "==========================================="
echo " DIAGNÓSTICO DO MOTOR TURBOPACK / NEXT.JS"
echo "==========================================="
echo ""
echo "[1] Verificando Versões do Sistema:"
echo " Node.js: \$(node --version)"
if command -v pnpm >/dev/null 2>&1; then
echo " pnpm: \$(pnpm --version)"
echo " Next.js: \$(pnpm list next 2>/dev/null | grep ' next ' | awk '{print \$2}' || echo 'Não listado')"
else
echo " pnpm: Não instalado"
echo " Next.js: (instale o pnpm para verificar a versão do pacote)"
fi
echo " Kernel: \$(uname -s) \$(uname -r)"
echo ""
echo "[2] Verificando Estado da Pasta .next:"
if [ -d ".next" ]; then
echo " Existe: Sim"
echo " Tamanho: \$(du -sh .next 2>/dev/null | awk '{print \$1}')"
echo " Modificado em: \$(stat -c %y .next 2>/dev/null || stat -f %Sm .next 2>/dev/null)"
else
echo " Existe: Não"
fi
echo ""
echo "[3] Processos do Next/Turbopack Ativos:"
PROCS=\$(ps aux | grep -E "next|turbopack" | grep -v grep || true)
if [ -n "\$PROCS" ]; then
echo "\$PROCS"
else
echo " Nenhum processo encontrado rodando."
fi
echo ""
echo "[4] Capacidade de Memória RAM Livre:"
if command -v free &>/dev/null; then
free -h | head -2
else
echo " Comando 'free' não disponível (SO sem suporte)."
fi
echo ""
echo "[5] Permissões das Pastas Internas:"
if [ -d ".next" ]; then
ls -la .next/ | head -n 5
fi
echo "==========================================="
echo " FIM DO DIAGNÓSTICO DO HOST"
echo "==========================================="
Resumo de decisão: qual solução aplicar#
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários