Post-mortem técnico de 14 de julho de 2026. Tudo o que se segue está documentado no bug 534655509 do Chromium.
Na manhã de 14 de julho, qualquer visitante do kiwop.com com Chrome 150 que clicasse num link via o separador morrer: ecrã "Aw, Snap!" e um código de erro, RESULT_CODE_KILLED_BAD_MESSAGE. A home carregava na perfeição. Cada página carregava na perfeição se entrasses diretamente pelo URL. Só partia ao navegar. Quatro horas depois o bug desapareceu sem termos tocado numa única linha, e essa é a parte mais interessante da história.
Esta é a crónica de como encurralámos o crash até ao código fonte do Chromium, porque é que a causa mais provável não estava no nosso site, e o que aprendemos sobre construir com APIs experimentais em produção.
O que tínhamos ativo: WebMCP
WebMCP é a API experimental do Chrome que permite a um site registar ferramentas para agentes de IA: expões funções com document.modelContext.registerTool() e um agente (uma extensão, um assistente do navegador) pode descobri-las e executá-las em vez de lutar com a tua interface a golpe de cliques simulados.
Tínhamo-la ativa através do origin trial oficial (Chrome 149 a 156), com o token numa etiqueta meta de todas as páginas. Duas ferramentas imperativas e uma declarativa no formulário do chat. Faz parte da nossa aposta no agentic browsing: que os agentes possam operar um site é o passo seguinte depois de poderem citá-lo.
Em Chrome 149 tudo funcionava. Com a chegada do Chrome 150 a estável, começou o espetáculo.
Um crash que os health checks não veem
O insidioso da falha é que toda a nossa monitorização estava verde. Os checks sintéticos pedem URLs e todos devolviam 200. O site estava "saudável" para qualquer robô de vigilância e avariado para qualquer humano que navegasse, porque o crash só disparava na navegação same-site iniciada com um clique, a que reutiliza o processo de render do Chrome.
Primeira lição operacional, que já transformámos em norma interna: depois de uma alteração importante, percorremos o site a cliques verdadeiros, num navegador a sério. Um 200 não diz que o site funciona, diz que o servidor responde.
A bissecção: quatro passos para o encurralar
Num ambiente de desenvolvimento reproduzimos o crash e fomos retirando peças, uma de cada vez:
- Ferramentas imperativas e declarativa ativas: crash.
- Só as imperativas, declarativa fora: crash.
- Origin trial ativo e zero ferramentas registadas (
getTools()devolve uma lista vazia): crash na mesma. - Sem o token do origin trial (a API nem sequer existe na página): navegação perfeita.
A conclusão era incómoda mas clara: não era o nosso uso da API. Bastava a presença do token para partir a navegação do site inteiro. Desligámos o WebMCP em produção e o site voltou ao normal na hora.
Aqui vai a segunda lição: o token vivia numa variável de ambiente, por isso desligar a feature custou minutos. Se estivesse incrustado nos templates, o site teria continuado avariado enquanto mexíamos em código contra o relógio. Toda a API experimental em produção precisa de um interruptor que a desligue.
O que diz o código do Chromium
Com o fogo apagado, investigámos a fundo. A primeira coisa que surpreende: ninguém tinha reportado este crash. Nem no tracker do Chromium, nem no repositório da especificação, nem no Stack Overflow. Éramos, que saibamos, os primeiros a vê-lo.
A segunda: o origin trial estava intacto no Chrome 150. A entrada oficial do Chrome Platform Status confirma o intervalo de milestones 149 a 156 sem alterações. A única coisa que mudou na 150 foi a superfície da API: navigator.modelContext ficou depreciado a favor de document.modelContext.
A terceira, e aqui está o quid da questão: comparámos o código do WebMCP entre os branches do Chrome 149 e 150, e é idêntico. O gating do origin trial, os bindings, tudo. A regressão não estava no código do WebMCP.
O que encontrámos, isso sim, é o mecanismo exato do erro. No processo principal do Chrome, o ficheiro model_context_user_data.cc vigia o estado do WebMCP documento a documento. Se o processo de render e o processo principal discordam sobre se o WebMCP está ativado para um documento concreto, o principal interpreta a mensagem do render como IPC ilegal e mata-o. Esse kill é literalmente o RESULT_CODE_KILLED_BAD_MESSAGE que víamos no ecrã. E não era a primeira vez que esta família de falhas mordia: uma CL de maio de 2026 corrigiu um crash idêntico na sua mecânica, quando o render acreditava que o WebMCP estava ativo e o processo principal não tinha dado por isso.
A reviravolta: o bug esfumou-se sem lhe tocarmos
À tarde tentámos reproduzir o crash num perfil limpo do Chrome, com o mesmo build exato (150.0.7871.115). Impossível. Testámos oito configurações, incluindo uma réplica exata do incidente: o mesmo site, o mesmo token, navegação com cliques reais. Nada.
E, umas horas depois, já nem reproduzia no navegador onde tinha crashado a manhã inteira. Mesmo build, mesmo perfil, mesmo site, mesmo token. Do nosso lado não tinha mudado absolutamente nada.
Quando uma falha 100% reproduzível desaparece sem nenhuma alteração do lado do cliente, a explicação que resta vive do lado do servidor. O Chrome ativa e desativa funcionalidades a quente através do Finch, o seu sistema de experiências remotas: a Google pode ligar uma variante numa percentagem das instalações e revertê-la com um killswitch em horas, sem atualizar o navegador. A nossa hipótese de trabalho, e é assim que a reportámos, é que uma experiência relacionada com o WebMCP se ativou nessa manhã, entrou em conflito com o estado por documento do origin trial e alguém na Google carregou no botão de desligar ao ver os crashes. Do nosso lado não conseguimos vê-lo; a Google pode verificá-lo no seu histórico de variações num minuto, e é exatamente isso que pedimos no reporte.
Fique registada a honestidade: é uma hipótese. O que é facto é a sequência temporal, os nove dumps de memória que os crashes deixaram no Crashpad local e que conservámos como prova, e que a falha morreu sozinha.
O que aprendemos, para o caso de construíres com APIs experimentais
- Um origin trial mete a Google no teu runtime. A feature pode mudar debaixo dos teus pés sem que tu faças deploy de nada. Assume isso no design: o experimental isola-se e pode desligar-se.
- Interruptor de desligar ou nada. Variável de ambiente, flag remota, o que for que desligue a feature em minutos sem tocar em templates.
- Os health checks não veem roturas de navegação. Depois de cada alteração séria, cliques reais num navegador real. Sem exceção.
- Faz bissecção com uma variável de cada vez. A nossa tabela de quatro passos é o que transforma "o meu site parte-se" num reporte que um engenheiro do Chromium pode acionar.
- Guarda os minidumps. O diretório Crashpad do Chrome é a caixa negra do acidente: os dumps da manhã são a única prova física que resta do incidente.
O reporte, e o que se passa agora
O caso completo está no bug 534655509, com as páginas de reprodução públicas que montámos para a equipa do Chromium. O WebMCP continua desligado no kiwop.com e vai voltar quando o bug tiver resposta ou quando o Chrome 151 chegar a estável, o que acontecer primeiro. No dia em que voltar, o site vai voltar a ser percorrido a golpe de clique antes de darmos nada por garantido.
Entretanto, a moral de fundo não muda: a web agêntica chega com APIs jovens, experiências remotas e erros que nenhum monitor clássico deteta. É terreno novo, e é exatamente onde trabalhamos. Se queres que o teu site esteja preparado para agentes sem arriscares a navegação pelo caminho, começa por uma auditoria de IA ou escreve-nos.
Perguntas frequentes
O que é o WebMCP?
O WebMCP é uma API experimental do Chrome, impulsionada pela Google e pela Microsoft no W3C, que permite a uma página web registar ferramentas para agentes de IA através de document.modelContext.registerTool(). Em julho de 2026 está em origin trial no Chrome desde a versão 149 até à 156, com lançamento estável previsto para a 157.
O que significa o erro RESULT_CODE_KILLED_BAD_MESSAGE do Chrome?
Significa que o processo principal do Chrome matou deliberadamente o processo de render de um separador por lhe enviar uma mensagem IPC que considera ilegal ou malformada. Não é um bloqueio do render: é uma execução defensiva, pensada para travar processos comprometidos. O utilizador vê isso como um ecrã "Aw, Snap!".
O que é o Finch, o sistema de experiências do Chrome?
O Finch é o mecanismo da Google para ativar ou desativar funcionalidades do Chrome remotamente, por percentagens de instalações e sem publicar uma atualização. Cada Chrome descarrega periodicamente uma "semente" de experiências que decide que variantes tem ativas. Permite lançamentos graduais e também killswitches: reverter em horas uma funcionalidade que está a causar problemas.
É arriscado ativar um origin trial em produção?
É assumível se o tratares como aquilo que é: código experimental cujo comportamento pode mudar sem que tu faças nada. As três regras que nos funcionam são isolar a feature atrás de um interruptor que a desligue em minutos, verificar o site navegando a sério depois de cada mudança de versão do Chrome, e monitorizar também os fluxos de navegação, não só os códigos de resposta.