Pular para o conteúdo
OmniRoute source

Troubleshooting (Português (Brasil))

Novo no OmniRoute? Comece aqui — estas soluções resolvem 90% dos problemas:

Vejo isto O que significa O que fazer
“Não foi possível conectar” O OmniRoute não está em execução Execute omniroute ou docker restart omniroute
“Chave de API inválida” Sua chave está incorreta ou expirou Copie novamente a chave no site do provedor
“Limite de requisições excedido” Você está enviando requisições demais Aguarde 1 minuto ou use model: "auto" para fallback automático
“Cota excedida” Você esgotou sua cota gratuita/paga Conecte mais provedores ou use provedores gratuitos (Kiro, Pollinations)
“Respostas lentas” O provedor está ocupado ou muito distante Use model: "auto/fast" ou conecte um provedor mais rápido (Groq, Cerebras)
“Provedor incorreto usado” auto escolheu um provedor diferente Isso é normal! auto escolhe o melhor. Force um provedor específico com model: "openai/gpt-4o"
“502 Bad Gateway” O provedor está indisponível Aguarde e tente novamente ou use model: "auto" para trocar de provedor
“401 Unauthorized” Suas credenciais estão incorretas Verifique sua chave de API ou autentique-se novamente com OAuth
“omniroute não é reconhecido” O PATH do Windows não inclui os módulos globais do node Adicione o prefixo global do npm ao PATH do Windows. Encontre-o com npm config get prefix.
“429 Too Many Requests” Limite de requisições atingido Aguarde 1 minuto ou conecte mais provedores

Ainda com problemas? Consulte a solução de problemas detalhada abaixo ou peça ajuda no Discord.



Limitação de requisições em provedores gratuitos (429 / 400 / 401)

Seção intitulada “Limitação de requisições em provedores gratuitos (429 / 400 / 401)”

Sintoma: Ao usar model: "auto" com provedores gratuitos/sem autenticação (opencode, auggie etc.), você recebe intermitentemente HTTP 429, 400 ou 401 em vez de respostas. As requisições são bem-sucedidas ao tentar novamente com o mesmo prompt alguns instantes depois, mas automações (tarefas cron, agentes, scripts) falham no primeiro erro.

Causa raiz: Três modos de falha independentes se acumulam:

  1. Limite de requisições do provedor (429): Os planos gratuitos podem impor uma cota por intervalo de tempo. Uma rajada de chamadas paralelas esgota essa cota; portanto, a próxima requisição é recusada até que o intervalo seja reiniciado.
  2. Modelo com falha no passthrough (400/401): Os pools auto/* podem incluir modelos passthrough do opencode que estão registrados no catálogo, mas não possuem credenciais ativas (por exemplo, oc/north-mini-code-free → 401). O roteador automático tenta um deles, falha, e o erro é propagado antes que o fallback seja acionado.
  3. Amplificação da concorrência (429 sob carga): Quando várias sessões de agentes/cron acessam auto ao mesmo tempo, a taxa agregada de requisições excede o que os provedores gratuitos toleram, fazendo com que chamadas legítimas sejam sinalizadas como abusivas.

Correção verificada (relatada pela comunidade, 2026-08-10): ajuste três variáveis de ambiente para que a rotação, a concorrência e o fallback absorvam a instabilidade dos planos gratuitos em vez de falharem por causa dela:

Janela do terminal
export OMNIROUTE_ROTATE_ON_400=true # muda para outro modelo/provedor em caso de 400/401 (ignora modelos passthrough com falha)
export OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=4 # limite explícito de admissão de requisições pesadas (por padrão, não definido: sem limite de contagem de requisições; consulte a observação abaixo)
export OMNIROUTE_CHAT_ADMISSION_QUEUE_MS=5000 # espera limitada mais longa por capacidade para requisições pesadas, em vez de um 503 imediato que permite nova tentativa

Defina essas variáveis no ambiente do processo do OmniRoute (o daemon, por exemplo, por meio do plist do LaunchAgent ou de systemctl edit) e reinicie o OmniRoute. A opção de rotação é, isoladamente, o recurso de maior impacto: ela transforma uma falha definitiva em uma nova tentativa transparente com um provedor saudável do pool.

Observação: OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT limita quantas requisições pesadas — de contexto longo — são executadas simultaneamente; o limite é um controle de admissão, não um limitador de requisições do provedor. Atualização sobre o fan-out de #503: essa variável não é mais definida por padrão (agora ela só é aplicada quando configurada explicitamente, como acima) — em vez disso, a admissão de requisições pesadas é controlada por um orçamento de bytes derivado automaticamente (OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES), que se ajusta ao limite real de memória do host. Portanto, uma implantação nova deve apresentar muito menos rejeições 503 chat_admission_busy sem que seja necessário definir essa variável; defini-la explicitamente aqui continua funcionando exatamente como documentado. Substituições explícitas do orçamento de bytes são limitadas ao intervalo de 8 MiB a 2 GiB. Um 413 body_exceeds_budget não é temporário: aumente esse orçamento de bytes, reduza OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES ou aumente o limite de memória do processo. Um descarte inflight_bytes_budget é uma contenção temporária e continua permitindo nova tentativa. A limitação de requisições por provedor (open-sse/services/rateLimitManager.ts) é controlada separadamente por RATE_LIMIT_MAX_WAIT_MS, RATE_LIMIT_MAX_QUEUE_DEPTH e RATE_LIMIT_AUTO_ENABLE — consulte .env.example.

Como verificar se funcionou: execute seu agente/cron duas vezes em rápida sucessão e confirme que ambas as execuções foram bem-sucedidas. Antes da correção, a segunda execução normalmente retorna 429/401. Após a correção, as falhas (se houver) são repetidas de forma transparente, e a chamada é concluída. Você também pode executar curl /monitoring/health e observar o campo rateLimitedUntil nas conexões dos provedores e circuitBreakers.providerBreakers[].state para os provedores afetados — o estado pode ser CLOSED, DEGRADED, OPEN ou HALF_OPEN (consulte src/shared/utils/circuitBreaker.ts), e um provedor que continua falhando mudará de CLOSED → DEGRADED → OPEN antes que a janela de redefinição permita a passagem de uma solicitação de teste (HALF_OPEN).

Se você ainda receber 429: a conta ativa desse provedor realmente esgotou sua cota (não apenas o limite de requisições). Adicione uma segunda conta para o mesmo provedor no painel do OmniRoute → Provedores → Contas, ou inclua outro provedor gratuito (por exemplo, routeway, auggie). A rotação só ajuda com erros transitórios de limite de requisições/400/401; o esgotamento total da cota exige uma segunda credencial ou um provedor diferente.

Se você receber 403 em modelos de visão (auto/vision, bazaarlink/*): a conta conectada não possui um plano pago que inclua visão, ou a chave da API não tem permissões suficientes. Verifique no painel do provedor se o escopo da chave inclui visão/multimodal ou conecte uma conta de nível pago e mantenha-a como destino para visão.


Avisos do npm install (ERESOLVE / peer / deprecated)

Seção intitulada “Avisos do npm install (ERESOLVE / peer / deprecated)”

Ao executar npm install -g omniroute, você poderá ver uma enxurrada de avisos como npm warn ERESOLVE, notificações sobre dependências peer e mensagens deprecated. Esses avisos são esperados e inofensivos. A instalação foi bem-sucedida se você vir added <N> packages na saída.

Para suprimir os avisos de resolução de dependências peer, use a forma de instalação compatível com o OmniRoute:

Janela do terminal
npm install -g omniroute --legacy-peer-deps

--legacy-peer-deps suprime apenas o ERESOLVE e as notificações sobre dependências peer. Os avisos de descontinuação permanecem visíveis porque são provenientes de pacotes transitivos de terceiros; eles não indicam que a instalação falhou.

Os avisos são causados por intervalos desatualizados de dependências peer em pacotes de terceiros que o OmniRoute não controla:

  1. marked-terminal requer marked >=1 <16, mas foi encontrado marked@18 — funciona normalmente na prática; o intervalo peer do projeto upstream está apenas desatualizado.
  2. deprecated prebuild-install@7.1.3 — um utilitário transitivo para obtenção de binários nativos. Ele não é usado para instalar o binding de transporte fixado wreq-js e não indica que a configuração de transporte do provedor de cookies da web falhou.

Nenhuma ação é necessária — os avisos não podem ser totalmente silenciados sem criar forks dos pacotes upstream.


Se uma solicitação do Gemini Web retornar 503 com uma mensagem informando que o Playwright Chromium não está instalado, o pacote npm está presente, mas o binário do navegador está ausente. O Playwright mantém deliberadamente os downloads dos navegadores separados da instalação do pacote npm, portanto essa resposta é esperada até que o navegador seja instalado.

Para uma instalação global do npm, instale o Chromium a partir do diretório do pacote OmniRoute para que o cache do navegador pertença à mesma instalação do Playwright:

Janela do terminal
cd "$(npm root -g)/omniroute"
npx playwright install chromium

Reinicie o OmniRoute após a instalação e tente novamente a solicitação do Gemini Web. Se você executar o OmniRoute a partir de uma imagem Docker, use a imagem -web (ou o alvo de build runner-web), que inclui o Chromium e suas dependências; a imagem base não inclui.


Problema Solução
O primeiro login não funciona Defina INITIAL_PASSWORD no .env (não há valor padrão fixo no código)
O painel abre na porta errada Defina PORT=20128 e NEXT_PUBLIC_BASE_URL=http://localhost:20128
Nenhum log é gravado no disco Defina APP_LOG_TO_FILE=true e verifique se a captura de logs de chamadas está habilitada
EACCES: permissão negada Defina DATA_DIR=/path/to/writable/dir para substituir ~/.omniroute
A estratégia de roteamento não é salva Atualize para a versão v3.x mais recente (a correção do esquema Zod para persistência das configurações foi incluída em versões anteriores)
Falha no login / página em branco Verifique a versão do Node.js — consulte Compatibilidade com o Node.js abaixo
dlopen / slice is not valid mach-o file (macOS) Execute cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute — consulte recompilação de módulo nativo no macOS abaixo
“fetch failed” no proxy Certifique-se de que a configuração do proxy esteja definida no nível correto — consulte Problemas de proxy abaixo
Docker curl: (56) Recv failure: Connection reset by peer O vínculo de porta do Docker pode estar sendo direcionado ao IPv6. Use -p 127.0.0.1:20128:20128 para forçar o IPv4 ou teste com curl -4. Consulte IPv6 no Docker abaixo
O antivírus coloca README.md em quarentena Falso positivo — consulte Falsos positivos de antivírus abaixo
O Kaspersky identifica o aplicativo Desktop como um Trojan Falso positivo comportamental no instalador não assinado — consulte Falsos positivos de antivírus abaixo

Avast/AVG coloca README.md em quarentena com MD:HttpRequest-inf[Susp]

Seção intitulada “Avast/AVG coloca README.md em quarentena com MD:HttpRequest-inf[Susp]”

Este é um falso positivo. Nada está infectado e nenhuma ação é necessária.

O Avast e o AVG executam uma heurística que sinaliza arquivos de texto simples/Markdown que contêm muitos links semelhantes a solicitações HTTP. O README.md do OmniRoute é distribuído dentro do pacote npm (ele está listado em package.json → files), portanto é instalado em node_modules/omniroute/README.md durante uma instalação global — e contém cerca de 15 exemplos de http://localhost:20128/... (os endpoints HTTP/SSE do MCP, a URL .well-known do A2A e trechos com curl). Essa densidade de links é suficiente para acionar a heurística.

Se isso começou apenas recentemente: o tipo de arquivo não mudou. O README teve sua tabela de endpoints ampliada (MCP HTTP + SSE + A2A foram adicionados), além de mais exemplos de curl, o que fez com que ultrapassasse o limite.

O arquivo é uma documentação inerte, sem nenhum conteúdo executável. Você pode restaurá-lo com segurança da quarentena.

O que fazer:

  1. Interrompa as notificações — exclua o diretório de instalação no seu antivírus (Avast: Configurações → Exceções), adicionando o caminho global de node_modules e/ou o diretório de dados do OmniRoute (~/.omniroute/).
  2. Relate o falso positivo — https://www.avast.com/false-positive-file-form.php, anexando o README.md em quarentena. Essa é a correção que ajuda a todos, pois se trata da heurística do fornecedor reagindo de forma excessiva a um arquivo de texto.

Por que não “corrigimos” isso do nosso lado: todos os exemplos usam http://localhost, e localhost não pode usar https sem o inconveniente de certificados autoassinados. Adulterar a documentação para contornar a heurística de um fornecedor prejudicaria todos os leitores para atender a um bug do mecanismo de verificação.

Kaspersky sinaliza o aplicativo Desktop como PDM:Trojan.Win32.Generic

Seção intitulada “Kaspersky sinaliza o aplicativo Desktop como PDM:Trojan.Win32.Generic”

Este é um falso positivo de uma heurística comportamental. Nada está infectado. O prefixo PDM: da Kaspersky significa que o veredito vem de seu Módulo de Defesa Proativa (System Watcher), que avalia o que o instalador faz, em vez de compará-lo com malware conhecido. Quando isso ocorre, a Kaspersky “reverte” toda a instalação — excluindo arquivos que já havia gravado — e, por isso, o aplicativo acaba corrompido ou ausente.

Os arquivos sinalizados são componentes padrão de dependências de código aberto declaradas e incluídas com o aplicativo para desktop, por exemplo:

  • resources/app/.build/next/node_modules/playwright-&lt;hash&gt;/lib/…/agentParser.js e workerProcessEntry.js — Playwright, a biblioteca de automação de navegador usada para login em provedores dentro do aplicativo e chat apoiado por navegador.
  • resources/app/.build/next/node_modules/@wreq-js/binding-win32-&lt;arch&gt;-msvc-&lt;hash&gt;/wreq-js.win32-&lt;arch&gt;-msvc.node — o binding nativo wreq-js com versão fixada, usado para HTTP com impressão digital de navegador em provedores baseados em cookies da web (&lt;arch&gt; é x64 ou arm64).

Por que isso ocorre: o instalador do Windows ainda não é assinado digitalmente, portanto um instalador NSIS não assinado não tem reputação alguma e as heurísticas comportamentais operam com agressividade máxima. Combinado com uma DLL nativa incluída e centenas de arquivos .js gravados em %LOCALAPPDATA%\Programs\OmniRoute (incluindo diretórios de pacotes com sufixos de hash da compilação standalone do Next.js), isso é suficiente para acionar a heurística. A assinatura de código está planejada; até que seja implementada, isso pode se repetir em novas versões.

O que fazer:

  1. Verifique primeiro o download (isso descarta a possibilidade de um arquivo adulterado). Cada versão publica latest.yml, cujo campo sha512 (base64) abrange o instalador OmniRoute.Setup.&lt;version&gt;.exe. No PowerShell, a partir da pasta que contém o instalador:
    Janela do terminal
    $b = [System.Security.Cryptography.SHA512]::Create().ComputeHash(
    [System.IO.File]::ReadAllBytes("$PWD\OmniRoute.Setup.&lt;version&gt;.exe"))
    [Convert]::ToBase64String($b)
    A saída deve corresponder a latest.yml → sha512. Caso contrário, exclua o arquivo e faça o download novamente apenas pela página de versões do GitHub.
  2. Restaure + exclua — restaure os itens revertidos da quarentena e adicione uma exclusão para %LOCALAPPDATA%\Programs\OmniRoute (Kaspersky → Configurações → Ameaças e Exclusões) e, em seguida, reinstale.
  3. Relate o falso positivo — https://opentip.kaspersky.com/. Relatos de falsos positivos enviados por usuários realmente aceleram a inclusão na lista de permissões.

A página de login trava ou exibe o erro “Module self-registration”

Seção intitulada “A página de login trava ou exibe o erro “Module self-registration””

Causa: Você está executando uma versão do Node.js fora da versão mínima de runtime seguro aprovada pelo OmniRoute. O caso mais comum é usar uma versão de patch mais antiga do Node 22 ou 24, abaixo da versão mínima de segurança com as correções exigidas pelo OmniRoute.

Sintomas:

  • A página de login exibe uma tela em branco ou um erro do servidor
  • O console exibe Error: Module did not self-register ou erros semelhantes de bindings nativos
  • A página de login exibe um banner de aviso laranja com sua versão do Node quando o runtime está fora da política segura compatível

Correção:

  1. Instale uma versão LTS compatível do Node.js (recomendado: Node.js 24.x):
    Janela do terminal
    nvm install 24
    nvm use 24
  2. Verifique sua versão: node --version deve exibir v24.0.0 ou uma versão mais recente da linha LTS 24.x
  3. Reinstale o OmniRoute: npm install -g omniroute
  4. Reinicie: omniroute

Versões seguras compatíveis: >=22.22.2 <23 ou >=24.0.0 <27. O Node.js 24.x LTS (Krypton) e o Node.js 26 são totalmente compatíveis.

npm v11+: better-sqlite3 não instalado (Cannot find module)

Seção intitulada “npm v11+: better-sqlite3 não instalado (Cannot find module)”

Causa: O npm v11 (incluído no Node.js 24+) bloqueia, por padrão, scripts de instalação de dependências opcionais. Como better-sqlite3 está listado em optionalDependencies e exige compilação nativa (node-gyp rebuild), o npm o ignora silenciosamente.

Sintomas:

  • O servidor trava durante a inicialização com Cannot find module 'better-sqlite3'
  • ls node_modules/better-sqlite3 exibe “No such file or directory”
  • npm ls better-sqlite3 exibe (empty)

Correção:

  1. Aprove os scripts de instalação e reinstale:
    Janela do terminal
    npm approve-scripts better-sqlite3
    npm install
  2. Ou instale manualmente o pacote pré-compilado:
    Janela do terminal
    npm pack better-sqlite3@13.0.1
    tar -xzf better-sqlite3-*.tgz -C node_modules
    mv node_modules/package node_modules/better-sqlite3
    rm better-sqlite3-*.tgz
  3. Verifique se funciona: node -e "require('better-sqlite3')(':memory:').close(); console.log('OK')"

macOS: dlopen / “slice is not valid mach-o file”

Seção intitulada “macOS: dlopen / “slice is not valid mach-o file””

Causa: Após um npm install -g omniroute global, o binário nativo do better-sqlite3 dentro do pacote pode ter sido compilado para uma arquitetura ou ABI do Node.js diferente daquela que está sendo executada localmente. Isso é comum no macOS (tanto no Apple Silicon quanto no Intel) quando o binário pré-compilado não corresponde ao seu ambiente.

Sintomas:

  • O servidor falha imediatamente durante a inicialização com um erro de dlopen
  • O erro contém slice is not valid mach-o file
  • Exemplo completo:
dlopen(/Users/&lt;user&gt;/.nvm/versions/node/v24.14.1/lib/node_modules/omniroute/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001): tried: '...' (slice is not valid mach-o file)

Correção — recompile para seu ambiente local (não é necessário fazer downgrade do Node.js):

Janela do terminal
cd $(npm root -g)/omniroute/app
npm rebuild better-sqlite3
omniroute

Observação: Isso recompila o binding nativo para sua versão local do Node.js e arquitetura de CPU, resolvendo a incompatibilidade do binário. O intervalo de runtime oficialmente compatível é >=22.22.2 <23 ou >=24.0.0 <27 (SUPPORTED_NODE_RANGE em src/shared/utils/nodeRuntimeSupport.ts, alinhado ao campo engines de package.json). O Node.js 24.x LTS (Krypton) e o Node.js 26 são totalmente compatíveis com o better-sqlite3 v12.x.


A validação do provedor exibe “fetch failed”

Seção intitulada “A validação do provedor exibe “fetch failed””

Causa: O endpoint de validação da chave de API (POST /api/providers/validate) anteriormente ignorava a configuração de proxy, causando falhas em ambientes que exigem roteamento por proxy.

Correção (v3.5.5+): Isso foi corrigido. A validação do provedor agora é roteada por runWithProxyContext, respeitando automaticamente as configurações de proxy no nível do provedor e globais.

A verificação de integridade do token falha com “fetch failed”

Seção intitulada “A verificação de integridade do token falha com “fetch failed””

Causa: A atualização de tokens OAuth em segundo plano não resolvia a configuração de proxy por conexão.

Correção (v3.5.5+): O agendador da verificação de integridade de tokens agora resolve a configuração de proxy por conexão antes de tentar a atualização. Atualize para a v3.5.5+.

O proxy SOCKS5 retorna “invalid onRequestStart method”

Seção intitulada “O proxy SOCKS5 retorna “invalid onRequestStart method””

Causa: No Node.js 22, o dispatcher do undici@8 é incompatível com a implementação integrada de fetch() do Node.

Correção (v3.5.5+): O OmniRoute agora usa a função fetch() do próprio undici quando um dispatcher de proxy está ativo, garantindo um comportamento consistente. Atualize para a v3.5.5+.

Proxy MITM no WSL: aplicativos de desktop no host Windows não são interceptados

Seção intitulada “Proxy MITM no WSL: aplicativos de desktop no host Windows não são interceptados”

Causa: O proxy MITM e seu certificado de CA são instalados no ambiente em que o OmniRoute é executado. No WSL, esse ambiente é o sistema Linux convidado, enquanto os aplicativos de IA para desktop (Kiro, Trae, Copilot, Zed, …) são executados no host Windows. Os aplicativos do host não confiam no repositório de certificados do sistema convidado nem fazem o roteamento pelo proxy do sistema convidado, portanto, a interceptação dos aplicativos de desktop não ocorre nesse cenário.

Recomendação: Execute o OmniRoute nativamente no mesmo SO que os aplicativos de desktop que você deseja interceptar (Windows para aplicativos Windows; o mesmo se aplica ao macOS/Linux). Manter o OmniRoute no WSL enquanto direciona o tráfego de aplicativos do host exige confiar manualmente no certificado de CA gerado no host Windows e configurar as definições de rede/proxy de cada aplicativo do host para usar o endpoint de proxy do WSL — uma configuração não compatível e frágil.


Causa: A cota do provedor foi esgotada.

Correção:

  1. Verifique o rastreador de cotas no painel
  2. Use uma combinação com níveis de fallback
  3. Mude para um nível mais barato/gratuito

Causa: A cota da assinatura foi esgotada.

Correção:

  • Adicione um fallback: cc/claude-opus-4-6 → glm/glm-4.7 → if/qwen3.8-max-preview
  • Use GLM/MiniMax como alternativa de baixo custo

O OmniRoute atualiza os tokens automaticamente. Se os problemas persistirem:

  1. Painel → Provedor → Reconectar
  2. Exclua e adicione novamente a conexão do provedor

Várias contas do Kiro: a segunda conta invalida a primeira

Seção intitulada “Várias contas do Kiro: a segunda conta invalida a primeira”

Causa: O backend do Kiro impõe uma única sessão ativa por registro de cliente OIDC. Quando duas contas compartilham o mesmo cliente registrado (conexões importadas antes da v3.8.0), a atualização do token de uma conta invalida o token de atualização da outra.

Correção (v3.8.0+): Importe novamente as conexões afetadas. A partir da v3.8.0, cada nova conexão do Kiro criada por meio de Importar token, Login social com Google/GitHub ou Importação automática registra automaticamente seu próprio cliente OIDC dedicado. Portanto, a conexão fica totalmente isolada, e a atualização de uma conta não afeta nenhuma outra conta.

As conexões importadas antes da v3.8.0 não têm um registro de cliente por conexão. Essas conexões continuam usando o endpoint compartilhado de atualização de autenticação social. Para obter isolamento, exclua a conexão antiga em Painel → Provedores e adicione-a novamente por meio de qualquer um dos três fluxos de importação.

Para obter detalhes completos e instruções passo a passo sobre como adicionar duas contas do Kiro lado a lado, consulte docs/guides/KIRO_SETUP.md.


  1. Verifique se BASE_URL aponta para sua instância em execução (por exemplo, http://localhost:20128)
  2. Verifique se CLOUD_URL aponta para seu endpoint na nuvem (por exemplo, https://omniroute.dev)
  3. Mantenha os valores NEXT_PUBLIC_* alinhados com os valores do lado do servidor

Sintoma: Unexpected token 'd'... no endpoint da nuvem para chamadas sem streaming.

Causa: O upstream retorna um payload SSE enquanto o cliente espera JSON.

Solução alternativa: Use stream=true para chamadas diretas à nuvem. O runtime local inclui fallback de SSE→JSON.

A nuvem indica conexão, mas exibe “Chave de API inválida”

Seção intitulada “A nuvem indica conexão, mas exibe “Chave de API inválida””
  1. Crie uma nova chave no dashboard local (/api/keys)
  2. Execute a sincronização com a nuvem: Habilitar nuvem → Sincronizar agora
  3. Chaves antigas/não sincronizadas ainda podem retornar 401 na nuvem

Sintomas: curl http://localhost:20128/v1/models retorna curl: (56) Recv failure: Connection reset by peer. O dashboard e os endpoints não autenticados funcionam, mas os endpoints autenticados falham — parece um problema de autenticação, mas não é.

Causa: docker run -p 20128:20128 publica tanto em 0.0.0.0 (IPv4) quanto em :: (IPv6), mas o processo dentro do contêiner escuta somente em IPv4. Em hosts nos quais localhost é resolvido primeiro como ::1, a conexão chega à porta IPv6 publicada sem nenhum processo escutando por trás dela → redefinição da conexão.

Correção:

  1. Diagnóstico rápido: Execute curl -4 http://localhost:20128/v1/models. Se funcionar com -4, mas falhar sem essa opção, há uma incompatibilidade de vinculação IPv6.
  2. Correção permanente: Vincule explicitamente ao IPv4 usando -p 127.0.0.1:20128:20128 no comando docker run:
    Janela do terminal
    docker run -d --name omniroute --restart unless-stopped --stop-timeout 40 \
    -p 127.0.0.1:20128:20128 -v omniroute-data:/app/data diegosouzapw/omniroute:latest
    Isso força a vinculação IPv4 e também evita expor o proxy em todas as interfaces do host.

  1. Verifique os campos do runtime: curl http://localhost:20128/api/cli-tools/runtime/codex | jq
  2. Para o modo portátil: use o destino de imagem runner-cli (CLIs incluídas)
  3. Para o modo de montagem do host: defina CLI_EXTRA_PATHS e monte o diretório de binários do host como somente leitura
  4. Se installed=true e runnable=false: o binário foi encontrado, mas falhou na verificação de integridade
Janela do terminal
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'

  1. Verifique as estatísticas de uso em Dashboard → Uso
  2. Altere o modelo principal para GLM/MiniMax
  3. Use o nível gratuito (Qoder, Kiro) para tarefas não críticas
  4. Defina limites de custo por chave de API: Dashboard → Chaves de API → Orçamento

Defina APP_LOG_TO_FILE=true no arquivo .env. Os logs da aplicação são gravados em logs/. Os artefatos das requisições são armazenados em ${DATA_DIR}/call_logs/ quando o pipeline de logs de chamadas está habilitado nas configurações. Quando a captura do pipeline estiver habilitada, defina CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS=false para omitir os payloads dos blocos de streaming ou ajuste CALL_LOG_PIPELINE_MAX_SIZE_KB para alterar o limite dos artefatos em KB.

Janela do terminal
# Dashboard de integridade
http://localhost:20128/dashboard/health
# Verificação de integridade da API
curl http://localhost:20128/api/monitoring/health
  • Estado principal: ${DATA_DIR}/storage.sqlite (provedores, combinações, aliases, chaves, configurações)
  • Uso: tabelas SQLite em storage.sqlite (usage_history, call_logs, proxy_logs) + ${DATA_DIR}/call_logs/ opcional
  • Logs da aplicação: &lt;repo&gt;/logs/... (quando APP_LOG_TO_FILE=true)
  • Artefatos de logs de chamadas: ${DATA_DIR}/call_logs/YYYY-MM-DD/... quando o pipeline de logs de chamadas está habilitado

A ação Limpar histórico da página Logs de requisições limpa call_logs, o request_detail_logs legado e o diretório local de artefatos ${DATA_DIR}/call_logs/.


Quando o circuit breaker de um provedor está OPEN, as solicitações são bloqueadas até que o período de espera termine.

Correção:

  1. Acesse Dashboard → Configurações → Resiliência
  2. Verifique o cartão do circuit breaker do provedor afetado
  3. Clique em Redefinir tudo para limpar todos os circuit breakers ou aguarde o período de espera terminar
  4. Antes de redefinir, confirme se o provedor está realmente disponível

Se um provedor entrar repetidamente no estado OPEN:

  1. Verifique o padrão de falhas em Dashboard → Integridade → Integridade dos provedores
  2. Acesse Configurações → Resiliência → Perfis de provedores e aumente o limite de falhas
  3. Verifique se o provedor alterou os limites da API ou exige uma nova autenticação
  4. Analise a telemetria de latência — uma latência alta pode causar falhas por tempo limite

  • Use um ID de modelo cujo primeiro segmento seja um provedor para o qual você tenha credenciais (openai/whisper-1, openrouter/deepgram/nova-3). Usar apenas deepgram/nova-3 exige uma chave nativa da Deepgram.
  • Verifique se o provedor está conectado em Dashboard → Provedores
  • Verifique os formatos de áudio compatíveis: mp3, wav, m4a, flac, ogg, webm
  • Verifique se o tamanho do arquivo está dentro dos limites do provedor (normalmente < 25 MB)
  • Verifique a validade da chave de API no cartão do provedor

Use Dashboard → Tradutor para depurar problemas de tradução de formatos:

Modo Quando usar
Área de testes Compare os formatos de entrada/saída lado a lado — cole uma solicitação com falha para ver como ela é traduzida
Testador de chat Envie mensagens em tempo real e inspecione o payload completo da solicitação/resposta, incluindo os cabeçalhos
Bancada de testes Execute testes em lote com diferentes combinações de formatos para descobrir quais traduções estão com problema
Monitor ao vivo Acompanhe o fluxo de solicitações em tempo real para identificar problemas intermitentes de tradução
  • As tags de raciocínio não aparecem — Verifique se o provedor de destino oferece suporte a raciocínio e confira a configuração do orçamento de raciocínio
  • As chamadas de ferramentas são descartadas — Algumas traduções de formato podem remover campos não compatíveis; verifique no modo Área de testes
  • O prompt do sistema está ausente — Claude e Gemini processam prompts do sistema de maneiras diferentes; verifique a saída da tradução
  • O SDK retorna uma string bruta em vez de um objeto — Resolvido na v1.x; o sanitizador de respostas remove campos não padronizados (x_groq, usage_breakdown etc.) que causam falhas na validação Pydantic do SDK da OpenAI. Se você ainda observar isso na v3.x+, registre um problema.
  • GLM/ERNIE rejeita a função system — Resolvido na v1.x; o normalizador de funções mescla automaticamente mensagens do sistema com mensagens do usuário para modelos incompatíveis. Se você ainda observar isso na v3.x+, registre um problema.
  • A função developer não é reconhecida — Resolvido na v1.x; ela é convertida automaticamente em system para provedores que não sejam a OpenAI. Se você ainda observar isso na v3.x+, registre um problema.
  • json_schema não funciona com o Gemini — Resolvido na v1.x; response_format agora é convertido em responseMimeType + responseSchema do Gemini. Se você ainda observar isso na v3.x+, registre um problema.

  • A limitação automática de taxa se aplica somente a provedores com chave de API (não a OAuth/assinatura)
  • Verifique se Configurações → Resiliência → Perfis de provedores está com a limitação automática de taxa habilitada
  • Verifique se o provedor retorna códigos de status 429 ou cabeçalhos Retry-After

Os perfis de provedores oferecem suporte a estas configurações:

  • Atraso base — Tempo de espera inicial após a primeira falha (padrão: 1s)
  • Atraso máximo — Limite máximo do tempo de espera (padrão: 30s)
  • Multiplicador — Quanto aumentar o atraso por falha consecutiva (padrão: 2x)

Quando muitas solicitações simultâneas atingem um provedor com limitação de taxa, o OmniRoute usa mutex + limitação automática de taxa para serializar as solicitações e evitar falhas em cascata. Isso é automático para provedores com chave de API.

Solicitações de chat falham com 503 / chat_admission_busy

Seção intitulada “Solicitações de chat falham com 503 / chat_admission_busy”

Sintomas:

  • O endpoint de conclusões de chat retorna uma resposta 503 que pode ser repetida, cujo código de erro é chat_admission_busy.
  • A resposta inclui Retry-After. Desde a #12135, o valor é derivado da ocupação observada — o maior valor entre a janela OMNIROUTE_CHAT_ADMISSION_QUEUE_MS pela qual a solicitação já esperou e o tempo durante o qual as concessões pesadas atuais foram mantidas — arredondado para cima para segundos inteiros e limitado a 60. Em um controle ocioso, ele mantém os limites mínimos históricos: 2 segundos no caminho baseado em bytes e 1 segundo no caminho baseado em estrutura (que também inclui reason: "structure_limit").
  • Isso pode acontecer enquanto outro chat pesado ou uma resposta de streaming de longa duração ainda está em andamento.

O corpo da resposta baseada em bytes é:

{
"error": {
"message": "Chat admission capacity is temporarily unavailable. Retry shortly.",
"type": "server_error",
"code": "chat_admission_busy"
}
}

A resposta baseada em estrutura usa o mesmo tipo e código, com a mensagem Local chat admission capacity is busy for this structurally heavy request; upstream provider routing was not attempted. Retry shortly. e reason: "structure_limit". Com os limites padrão, uma solicitação é estruturalmente pesada quando contém pelo menos 200 mensagens, pelo menos 64 ferramentas ou pelo menos 32,000 tokens estimados, ou quando a estimativa limitada da estrutura esgota seus limites de 10,000 nós visitados ou profundidade 12.

Causa: Essa é uma redução deliberada de carga dentro do OmniRoute, não uma falha do provedor upstream. Cada processo usa uma proteção local ao processo para reservar uma capacidade pesada limitada antes de reter e analisar o corpo de uma solicitação grande. Uma concessão pesada permanece ativa durante toda a duração de uma resposta SSE.

Propagação de #503: antes dessa correção, a proteção limitava a simultaneidade a uma CONTAGEM fixa de solicitações (OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT, padrão 1), independentemente da memória do host, de modo que a propagação de agentes de programação (vários subagentes/CLIs, com corpos normalmente > 256 KB) reduzia a simultaneidade efetiva para aproximadamente 1 e resultava em respostas 503 sob uma carga totalmente normal. Agora, a proteção se autoajusta: ela é controlada por um orçamento de BYTES de ingestão derivado automaticamente (OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES), dimensionado com base no limite real de memória do processo, e também consulta um sinal ativo de pressão sobre recursos — assim, ela só reduz a carga quando o host está realmente sob pressão de memória, e não apenas porque mais de uma solicitação pesada chegou ao mesmo tempo. O antigo limite de contagem (OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT) ainda é respeitado, mas somente se você o definir explicitamente.

Quando a capacidade está ocupada, uma solicitação pesada primeiro aguarda até OMNIROUTE_CHAT_ADMISSION_QUEUE_MS (padrão 2000; 0 desabilita a espera) para que uma vaga seja liberada antes de retornar a resposta 503 que pode ser repetida. A espera limitada existe para que clientes no estilo de agentes (OpenCode, Claude Code, Cursor) que distribuem simultaneamente várias subsolicitações pesadas serializem o pico em vez de consumirem todo o seu orçamento de novas tentativas com rejeições imediatas e falharem no meio da tarefa. A ocupação atual das concessões pesadas, o orçamento de bytes calculado e a gravidade da pressão ativa são expostos em GET /api/monitoring/health → chatAdmission (inflightBytes, maxInflightBytes, budgetSource, pressureSeverity, countCapEnabled) — verifique esses valores antes de alterar qualquer variável de ambiente. Configurações → Resiliência → Fila de solicitações → Solicitações simultâneas não controla isso; essa configuração rege um mecanismo separado de fila de solicitações do provedor.

Correção:

  1. Primeiro, tente novamente. Os clientes devem respeitar Retry-After e usar recuo em vez de repetir a solicitação imediatamente.
  2. Verifique /api/monitoring/health → chatAdmission antes de ajustar qualquer coisa. countCapEnabled: false e um maxInflightBytes generoso significam que o orçamento derivado automaticamente já está cumprindo sua função; um pressureSeverity igual a high/critical significa que o host está realmente com pouca memória — isso não pode ser corrigido por uma variável de ambiente de admissão; é necessário mais RAM ou uma carga de trabalho menor.
  3. Somente se /api/monitoring/health mostrar que o orçamento derivado automaticamente é realmente pequeno demais para seu host (algo raro — ele já se ajusta de contêineres a bare metal), substitua-o diretamente com OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES em vez de recorrer ao limite legado de contagem de solicitações.

Consulte a referência de variáveis de ambiente para ver as configurações oficiais de admissão.


Taxonomia opcional de falhas de RAG / LLM (16 problemas)

Seção intitulada “Taxonomia opcional de falhas de RAG / LLM (16 problemas)”

Alguns usuários do OmniRoute posicionam o gateway na frente de stacks de RAG ou de agentes. Nessas configurações, é comum observar um padrão estranho: o OmniRoute parece íntegro (provedores ativos, perfis de roteamento corretos, nenhum alerta de limite de requisições), mas a resposta final ainda está errada.

Na prática, esses incidentes geralmente têm origem no pipeline de RAG downstream, e não no próprio gateway.

Se você quiser um vocabulário compartilhado para descrever essas falhas, poderá usar o WFGY ProblemMap, um recurso de texto externo sob a licença MIT que define dezesseis padrões recorrentes de falhas de RAG / LLM. Em linhas gerais, ele abrange:

  • desvio na recuperação e limites de contexto rompidos
  • índices e armazenamentos vetoriais vazios ou desatualizados
  • incompatibilidade entre embeddings e semântica
  • problemas na montagem de prompts e na janela de contexto
  • colapso lógico e respostas excessivamente confiantes
  • falhas em cadeias longas e na coordenação de agentes
  • desvio de memória e de função em sistemas multiagente
  • problemas na ordem de implantação e inicialização

A ideia é simples:

  1. Ao investigar uma resposta ruim, registre:
    • a tarefa e a solicitação do usuário
    • a combinação de rota ou provedor no OmniRoute
    • qualquer contexto de RAG usado downstream (documentos recuperados, chamadas de ferramentas etc.)
  2. Associe o incidente a um ou dois números do WFGY ProblemMap (No.1 … No.16).
  3. Armazene o número em seu próprio painel, runbook ou rastreador de incidentes, junto aos logs do OmniRoute.
  4. Use a página correspondente do WFGY para decidir se é necessário alterar sua stack de RAG, seu recuperador ou sua estratégia de roteamento.

O texto completo e as instruções práticas estão disponíveis aqui (licença MIT, somente texto):

README do WFGY ProblemMap

Você pode ignorar esta seção se não executar pipelines de RAG ou de agentes por trás do OmniRoute.


Problemas específicos da versão v3.8.0 e suas soluções alternativas atuais. Se uma correção for incluída em um patch posterior, a entrada será atualizada ou removida.

Sintomas:

  • “Devin CLI not found” ou “auth failed” ao invocar ferramentas baseadas no Devin
  • A verificação de runtime da CLI relata installed=false

Causas:

  • CLI_DEVIN_BIN aponta para um caminho que não existe
  • A Devin CLI não está instalada no host

Correção:

  1. Instale a Devin CLI para sua plataforma
  2. Defina CLI_DEVIN_BIN=/usr/local/bin/devin (ou o caminho real) no .env
  3. Reinicie o OmniRoute e teste novamente em Painel → Ferramentas CLI

Sintomas:

  • Um modelo continua listado em cooldown mesmo após o término do período de expiração
  • As solicitações ainda ignoram o modelo no roteamento combinado, apesar de o timestamp estar no passado

Redefinição manual:

  • Painel: Configurações → Cooldowns de modelos → clique em Reativar no cartão afetado
  • API: DELETE /api/resilience/model-cooldowns com os cabeçalhos de autenticação de gerenciamento

Falha na conexão com o provedor Command Code com erro 403

Seção intitulada “Falha na conexão com o provedor Command Code com erro 403”

Sintomas:

  • Erro 403 ao testar a conexão com o provedor Command Code
  • O cartão do provedor mostra “unauthorized” após uma nova adição

Causa: O fluxo OAuth não foi concluído (o callback não foi recebido ou o token não foi persistido).

Correção:

  • Execute omniroute providers pela CLI para acionar novamente o fluxo OAuth, ou
  • Execute novamente o OAuth em Painel → Provedores → Command Code → Reconectar

Sintomas:

  • Cooldowns muito curtos ou imediatos no ModelScope após uma pequena rajada de solicitações
  • O roteamento combinado ignora o ModelScope antes do esperado

Causa: O ModelScope emite cabeçalhos Retry-After específicos do provedor. A v3.8.0 inclui um tratamento dedicado para esses cabeçalhos, portanto, versões anteriores os interpretam incorretamente como indicações genéricas de limite de requisições.

Correção:

  • Certifique-se de estar usando a v3.8.0 ou posterior
  • Verifique se a opção useUpstream429BreakerHints está ativada em Configurações → Resiliência

Sintomas:

  • Erro 401 em todas as solicitações à ponte WebSocket do Codex/Responses durante a execução em um host de produção remoto
  • O handshake da ponte WebSocket é encerrado imediatamente após a conexão

Causa: A variável de ambiente OMNIROUTE_WS_BRIDGE_SECRET está ausente no ambiente de produção.

Correção:

  1. Gere um segredo aleatório: openssl rand -hex 32
  2. Defina OMNIROUTE_WS_BRIDGE_SECRET=&lt;random-secret&gt; no ambiente do servidor de produção (e em qualquer cliente que se comunique com a ponte)
  3. Reinicie o OmniRoute

Responses API: modo em segundo plano degradado para síncrono

Seção intitulada “Responses API: modo em segundo plano degradado para síncrono”

Sintomas:

  • Aviso registrado: background mode degraded to synchronous
  • Uma solicitação com background: true retorna uma resposta síncrona normal em vez de um identificador de tarefa em segundo plano

Causa: A v3.8.0 degrada intencionalmente background: true na Responses API para execução síncrona, enquanto emite um aviso. A execução assíncrona completa em segundo plano será disponibilizada futuramente.

Correção:

  • Ajuste o cliente para realizar a chamada sem background, ou
  • Aguarde uma versão posterior que inclua o modo assíncrono completo em segundo plano (acompanhe o changelog)

Inicialização lenta / Tempo limite de prontidão

Seção intitulada “Inicialização lenta / Tempo limite de prontidão”

Se a CLI exibir ⚠ Server did not respond within 60s, mas o servidor estiver funcionando, o limite de tempo da verificação de prontidão é muito curto para o seu ambiente.

Isso geralmente acontece no Windows (antivírus, monitores do sistema de arquivos) ou em contêineres com cargas de trabalho pesadas durante a inicialização.

Correção — aumente o limite de tempo:

Janela do terminal
# Via variável de ambiente (persiste entre inicializações):
export OMNIROUTE_READY_TIMEOUT_MS=180000 # 3 minutos
omniroute serve
# Via flag da CLI (apenas uma vez):
omniroute serve --ready-timeout 180000

O padrão é 60 000 ms (60 s). O aviso é apenas informativo; o servidor continua sendo inicializado em segundo plano e ficará acessível assim que a inicialização for concluída.

Consulte docs/reference/ENVIRONMENT.md para obter todos os detalhes sobre OMNIROUTE_READY_TIMEOUT_MS.



Código-fonte do OmniRoute (a58000c7685f)

HagiCode

HagiCode é um ambiente de programação com agentes, fluxos estruturados, execução multiagente e visualizações Hero Dungeon.

Transforme ideias em software útil com um fluxo de trabalho com agentes mais inteligente, rápido e agradável.

Interface principal do HagiCode no tema claro
  • SmartFluxos estruturados transformam intenções em um caminho executável da ideia à entrega.
  • EfficientFluxos multiagente mantêm pesquisa, implementação e revisão em andamento simultaneamente.
  • FunO Hero Dungeon torna longas sessões de programação mais visuais e colaborativas.
Acessar HagiCode