Descrição
Quando a API Gemini do Google recusa uma solicitação com promptFeedback.blockReason, o Discourse AI trata a resposta como uma resposta bem-sucedida, porém vazia. Na tradução por IA, isso tem dois efeitos: o tópico ou a publicação nunca recebe um idioma detectado, portanto nunca é traduzido, e o backfill envia a mesma solicitação bloqueada novamente em execuções posteriores. Nada indica a um administrador que um bloqueio ocorreu.
Observado em um site auto-hospedado executando release/2026.7 (2026.7.3, commit f1caa6321287f918644fba9ff8943579fdcf027a) com o plugin discourse-ai integrado. A solicitação era a detecção de idioma de um título de tópico, usando o agente de detector de idioma integrado em gemini-3.5-flash-lite. O título era uma frase curta e inofensiva em sueco. O mesmo título foi traduzido por gemini-3.8-flash sem um bloqueio.
O Google respondeu com HTTP 200 e um único evento de stream sem candidatos:
data: {"promptFeedback": {"blockReason": "PROHIBITED_CONTENT"},"usageMetadata": {"promptTokenCount": 417,"totalTokenCount": 417,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 417}],"serviceTier": "standard"},"modelVersion": "gemini-3.5-flash-lite","responseId": "..."}
A solicitação já carrega BLOCK_NONE para as quatro categorias de segurança que o Discourse AI define, portanto este bloqueio não é um daqueles influenciados por essas configurações. O log de auditoria registra response_status 200.
Causa raiz
DiscourseAi::Completions::Endpoints::Gemini#decode_chunklê apenascandidatesde cada evento de stream.promptFeedbacknunca é inspecionado, portanto uma solicitação bloqueada produz um resultado vazio sem erro.DiscourseAi::Translation::LanguageDetector#detectretornanilquando a resposta não corresponde ao seu padrão de tag de idioma, o que é o caso para uma resposta vazia. O tópico ou a publicação mantémlocalecomo NULL.Jobs::TopicsLocaleDetectionBackfillseleciona tópicos comlocaleNULL em cada execução e não tem limite de tentativas, portanto, lendo o código, a solicitação bloqueada é repetida a cada cinco minutos por quanto tempo o tópico estiver na janela de backfill. Publicações são limitadas a duas tentativas de detecção por dia pela cota de relocalize, e são reenviadas a cada dia.- Candidatos de tradução requerem um locale detectado, portanto o item nunca é traduzido.
O mesmo código está presente em main desde 2026-10-03.
Correção sugerida
- Detectar
promptFeedback.blockReasonno endpoint Gemini e levantar ou registrar um erro distinto e visível que nomeie o motivo. - Registrar a falha contra o tópico ou a publicação para que o backfill pare de repetir uma solicitação que será bloqueada novamente, ou aplicar um limite de tentativas à detecção de tópico, como já existe para publicações.
- Exibir itens bloqueados na página de administração de tradução, para que um administrador possa definir o idioma manualmente.
Reproduzir
O bloqueio depende do filtro do Google e não pode ser forçado com uma entrada conhecida. Chamadas afetadas podem ser encontradas no log de auditoria:
SELECT id, created_at, language_model, post_id, topic_id, response_status
FROM ai_api_audit_logs
WHERE feature_name = 'translation'
AND raw_response_payload LIKE '%blockReason%'
ORDER BY created_at
Solução alternativa
Definir o idioma do tópico manualmente permite que a tradução prossiga. Neste site, o modelo de tradução não bloqueou o mesmo texto.