Um navegador na nuvem com rate limit não derruba mais o browser_exec

Você configurou um navegador na nuvem para o Hermes tirar um print do seu dashboard toda manhã e jogar num canal. Funcionou a semana inteira e, numa manhã, em vez do gráfico você recebe um erro: returned no CDP endpoint, so Browser Use mode cannot drive it. A página está bem. Seu script está bem. O serviço de navegador na nuvem estava aplicando rate limit por um instante — e toda a tarefa de navegador morreu junto.
O mais estranho: as ferramentas browser_* integradas do Hermes continuaram funcionando exatamente nas mesmas condições. Só o browser_exec caiu.
Duas formas pelas quais o navegador travava
Os dois sintomas vêm da mesma coisa. Depois que um navegador na nuvem é configurado (browser.cloud_provider, escolhido entre browserbase, browser-use, camofox, nous ou local), ainda deveria haver um caminho local disponível na máquina — mas o browser_exec não chegava até ele.
Um: a criação da sessão falha, a chamada falha
Quando o provedor na nuvem falhava na criação da sessão, o browser_exec falhava de vez:
Cloud browser provider BrowserUseBrowserProvider returned no CDP endpoint,
so Browser Use mode cannot drive it. Switch to the built-in browser tools
for this provider.
A falha vista ao vivo foi um rate limit: o gateway respondeu 429 RATE_LIMIT_EXCEEDED, com retryAfter 17 e limit 200.
A causa raiz é que o browser_exec e as ferramentas integradas não seguiam o mesmo caminho. As ferramentas de navegador integradas já recorrem ao Chromium local empacotado quando não conseguem criar uma sessão local, marcando a sessão como fallback_from_cloud. O browser_exec só lia cdp_url dessa sessão — e uma sessão local não tem cdp_url até o Chromium dela iniciar. Então ele lançava o erro acima e culpava o provedor.
Há também um amplificador: a sessão que falhou fica em cache. Chamadas seguintes com a mesma session key continuavam batendo na mesma sessão quebrada até o reaper de inatividade removê-la. Um único 429 podia derrubar os minutos seguintes de trabalho com o navegador.
O ajuste é deliberadamente pequeno. Em tools/browser_use_cli.py::_resolve_backend_cdp, quando a sessão do provedor volta como fallback_from_cloud, resolva o endpoint CDP do Chromium empacotado do mesmo jeito que o caminho sem provedor faz, e registre a falha do provedor uma vez só. Um provedor que devolve uma sessão sem CDP URL e sem fallback ainda falha com a mesma mensagem — nada finge funcionar.
Dois: o navegador na nuvem não alcança seu localhost
O segundo sintoma é mais comum: você tem um servidor de dev nesta máquina, pede http://localhost:3000 e recebe:
Blocked: URL targets a private or internal address
O browser_exec pré-analisa as URLs do seu código por segurança, mas chamava essa checagem sem o veredito do roteamento híbrido. Com cloud_provider definido, o backend conta como não local, então toda URL privada era rejeitada.
O browser_navigate nunca teve esse problema — ele roteia URLs privadas para um sidecar local. Dois caminhos dentro de um mesmo subsistema de navegador, dois comportamentos diferentes; esta mudança os alinha.
Qual URL vai para onde
| Endereço que você acessa | Quem abre |
|---|---|
https://example.com |
o navegador na nuvem configurado |
http://localhost:3000 |
sidecar local de Chromium sob a chave de cache ::local |
http://192.168.1.9 (LAN) |
sidecar local de Chromium |
169.254.169.254 (metadados da nuvem) |
bloqueado incondicionalmente, sem backend |
| uma chamada que mistura URLs públicas e privadas | a chamada inteira roda local |
Alguns detalhes de implementação importam porque são essenciais para a segurança:
- O predicado de rota
_hybrid_routes_locally(url)agora é compartilhado porbrowser_navigateebrowser_exec, então os dois não podem divergir; - Cada URL no código é avaliada uma única vez, e esse veredito decide tanto a checagem de segurança quanto a rota. Um host que resolve como privado e depois se religa a um IP público não consegue afrouxar a checagem de endereços privados e ainda assim ser enviado para a nuvem;
- Uma chamada que mistura URLs públicas e privadas roda inteiramente local — a parte privada nunca vaza para cima;
- O sidecar usa a chave de cache
::locale roda sob seu próprio harness daemon (BU_NAME=_local_<name>). O daemon lê seu ambiente CDP uma vez no start, então compartilhar o daemon da rota da nuvem repassaria a URL privada ao navegador na nuvem. Daemons separados, não um compartilhado; - Uma chamada seguinte sem literal de URL permanece na rota que a chamada anterior tomou.
O piso de segurança não se moveu
Fallbacks são um lugar fácil de introduzir um furo, então todas as invariantes existentes foram mantidas:
- Endereços de metadados da nuvem continuam bloqueados incondicionalmente:
169.254.169.254ainda responde “URL targets a cloud metadata endpoint”, independentemente do provedor; browser.auto_local_for_private_urlsvem ligado por padrão; colocá-lo emfalseainda rejeita URLs privadas, a menos que você também definabrowser.allow_private_urls, o que deixa o provedor na nuvem tentar — geralmente em vão, já que Browserbase e companhia não alcançam sua LAN;- Um override de CDP não é tratado como local: se você definir
browser.cdp_urlou usar/browser connect, o roteamento híbrido retorna falso e o comportamento segue igual; - Um redirecionamento de público para privado é recusado, não vazado;
- A rechecagem da URL final após a execução não foi tocada.
O fallback local precisa do sidecar local — a mesma CLI agent-browser que o modo puramente local usa. hermes setup tools → Browser Automation instala para você.
Status e atualização
Os dois ajustes (PRs #136447 e #136442) foram mesclados na main em 2026-10-11. A tag atual, v0.21.6 de 8 de outubro, não os inclui; a próxima release incluirá. Para usá-los hoje, atualize a partir da main.
Depois de atualizar, dá para confirmar que o fallback entrou procurando aquela única linha de falha do provedor no log — ela aparece uma vez, e a chamada do navegador segue no Chromium local.
Para fechar
Um navegador na nuvem é rápido e prático, mas é um serviço externo: aplica rate limit e sai do ar. A configuração que realmente se sustenta é nuvem primeiro, local como piso, e endereços sensíveis que nunca saem da máquina. Esse piso é o que estas mudanças restauram: a queda de um provedor não encerra mais sua tarefa, servidores de dev e páginas da LAN abrem como antes, e nem endereços internos nem endpoints de metadados da nuvem chegaram perto da nuvem.
Leitura relacionada: como as ferramentas de navegador integradas viraram o padrão explica a escolha de provedor, o orçamento de snapshots do navegador trata de outro tipo de “o navegador está lento”, e os desafios do navegador no plano gratuito cobre os trade-offs de rodar um navegador na nuvem com orçamento apertado.