> ## Documentation Index
> Fetch the complete documentation index at: https://x-preview-mintlify-d8d2882f.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Solução de problemas

> Diagnostique problemas comuns de criptografia do X Chat, incluindo erros do Chat XDK, recuperação do backup seguro de chave, falhas de descriptografia e montagem de payloads de envio assinados.

Esta página cobre problemas **específicos da criptografia do X Chat e do Chat XDK** — chaves, backup seguro de chave, descriptografar/verificar e montagem de payloads de envio criptografados.

Para webhooks, OAuth, códigos de status HTTP e limites de taxa, use a documentação geral da [API do X](/pt/x-api/introduction) e de [autenticação](/pt/fundamentals/authentication/overview).

***

## Chaves e backup seguro de chave

### Unlock falha (código de acesso inválido)

* Confirme que o código de acesso corresponde ao usado com `setup`
* Aguarde entre tentativas; os realms limitam a taxa de tentativas incorretas e podem bloquear a recuperação após falhas demais

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    try:
        chat.unlock(passcode)
    except ValueError as e:
        print(e)  # may mention InvalidPin or guesses remaining
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    try {
      await chat.unlock(passcode);
    } catch (e) {
      console.error((e as Error).message);
    }
    ```
  </Tab>

  <Tab title="Rust">
    ```rust theme={null}
    chat.unlock(passcode_bytes).await?;
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    if err := chat.Unlock(passcode, juiceboxConfigJSON); err != nil {
        log.Println(err)
    }
    ```
  </Tab>

  <Tab title="C#">
    ```csharp theme={null}
    try { chat.Unlock(passcode, juiceboxConfigJson); }
    catch (Exception e) { Console.WriteLine(e.Message); }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    try { chat.unlock(passcode, juiceboxConfigJson); }
    catch (Exception e) { System.out.println(e.getMessage()); }
    ```
  </Tab>
</Tabs>

### Criptografia ou descriptografia falha porque as chaves ou a identidade não estão definidas

Carregue as chaves privadas primeiro e depois defina a **identidade da sessão** — seu ID de usuário mais o `public_key_version` do seu registro no X. Os métodos `encrypt_*` e `prepare_*` assinam com ela; chamá-los sem uma identidade de sessão (e sem um override explícito por chamada) é um erro.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    chat.unlock(passcode)  # or: chat.import_keys(blob)
    chat.set_identity(my_user_id, signing_key_version)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    await chat.unlock(passcode);
    chat.setIdentity(myUserId, signingKeyVersion);
    ```
  </Tab>

  <Tab title="Rust">
    ```rust theme={null}
    chat.import_keys(&blob)?;
    chat.set_identity(&my_user_id, &signing_key_version);
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    blob, _ := chatxdk.Base64ToBytes(privateKeysB64)
    _ = chat.ImportKeys(blob)
    _ = chat.SetIdentity(myUserID, signingKeyVersion)
    ```
  </Tab>

  <Tab title="C#">
    ```csharp theme={null}
    chat.ImportKeys(blobBytes);
    chat.SetIdentity(myUserId, signingKeyVersion);
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    chat.importKeys(blobBytes);
    chat.setIdentity(myUserId, signingKeyVersion);
    ```
  </Tab>
</Tabs>

### Chave de conversa ausente para uma mensagem

Um erro como `Message encrypted with key version '…' but no matching key found` significa que você não tem a chave em **bruto** para o `conversation_key_version` daquela mensagem.

1. Descriptografe o material de chave de `conversation_key_change_event` (eventos ao vivo) ou `meta.conversation_key_events` (histórico) com `extract_conversation_keys`, **ou** inclua esses blobs em `decrypt_events` — com `set_cache_keys(true)` habilitado, `decrypt_events` também retém a chave verificada mais recente de cada conversa, de modo que chamadas posteriores de `decrypt_event` e `encrypt_*` podem omiti-la
2. Confirme que as chaves de conversa foram adicionadas para aquela versão e que você ainda é um participante (veja [Primeiros passos](/pt/xchat/getting-started#4-set-up-conversation-keys))

### O peer não tem chaves públicas

Talvez ele não tenha concluído o onboarding. Depois que ele se registrar, carregue `public_key`, `signing_public_key`, `identity_public_key_signature` e `public_key_version` em **Referência da API → Chaves de criptografia**.

***

## Descriptografia e assinaturas

### Descriptografia falha

* Chave da conversa em **bruto** obsoleta ou incorreta, ou versão de chave errada
* String `encoded_event` incompleta
* O tipo de evento não é uma mensagem criptografada que você possa tratar como conteúdo descriptografável

### A assinatura não é verificada

A verificação é **fail-closed por padrão** (`reject_unverified = true`): o SDK já rejeita eventos assinados não verificados, então uma falha aqui significa que as entradas de verificação estão erradas, não que você precisa ligar a checagem. Causas comuns:

* Entrada de chave de assinatura ausente ou incompleta para o **remetente** (todos os campos exigidos pelo Chat XDK — veja a referência do [Chat XDK](/pt/xchat/xchat-xdk))
* Nenhuma chave de assinatura passada na chamada nem armazenada via `set_signing_keys`
* O remetente rotacionou as versões — busque suas chaves públicas novamente
* Uma versão de chave abaixo do piso aceito nunca é verificada

O setter `set_reject_unverified` existe para **desabilitar** esse padrão (`false`, não recomendado). Se você o desabilitou anteriormente, restaure o padrão fail-closed:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    chat.set_reject_unverified(True)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    chat.setRejectUnverified(true);
    ```
  </Tab>

  <Tab title="Rust">
    ```rust theme={null}
    chat.set_reject_unverified(true);
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    chat.SetRejectUnverified(true)
    ```
  </Tab>

  <Tab title="C#">
    ```csharp theme={null}
    chat.SetRejectUnverified(true);
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    chat.setRejectUnverified(true);
    ```
  </Tab>
</Tabs>

### Uma resposta traz `reply_preview_validation: "Invalid"`

Respostas descriptografadas podem trazer `reply_preview_validation` (`"Valid"` / `"Invalid"`; JavaScript usa `'valid'` / `'invalid'`). `Invalid` significa que o preview citado dentro da mensagem não corresponde ao evento original assinado que ela incorpora — trate a citação como não confiável e renderize o conteúdo citado apenas a partir do original validado. A mensagem em si é verificada separadamente e continua autêntica; nada é lançado por um preview inválido.

### Eventos antigos falham permanentemente na verificação

Erros como `signature missing or no matching signing key` ou um mismatch de ECDSA em **eventos antigos** são permanentes. Assinaturas são imutáveis e verificadas reconstruindo o payload assinado a partir do próprio evento, então um evento assinado sobre bytes diferentes (ou nunca assinado) falha em toda carga futura — nenhuma retentativa, atualização de chave ou chamada de API pode consertá-lo. Trate esses eventos como tombstones, não como erros com retentativa. Rotacionar a chave da conversa inicia um histórico limpo e verificável a partir desse ponto; novas mensagens não são afetadas.

***

## Montando o payload de envio

Estes erros são específicos da criptografia do X Chat (não erros HTTP gerais):

| Problema                    | Correção                                                                                                                                                                                                                                       |
| :-------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bytes de chave incorretos   | Passe os bytes da chave da conversa em **bruto** para o Chat XDK, não a string de chave criptografada da API                                                                                                                                   |
| Nomes de campo JSON errados | Mapeie `encrypted_content` → `encoded_message_create_event` e `encoded_event_signature` → `encoded_message_event_signature`                                                                                                                    |
| ID de mensagem errado       | Envie o `message_id` do payload retornado — o SDK o gera e o incorpora ao evento assinado, então qualquer outro valor falha. Em retentativas, reutilize o mesmo payload criptografado para que o ID nunca seja gerado duas vezes               |
| Descompasso de versão       | Alinhe `conversation_key_version` com a chave que você usa; alinhe a versão da chave de assinatura passada para `set_identity` com seu registro de chave pública                                                                               |
| Forma do ID no caminho      | Caminhos de URL ainda precisam do ID da conversa com hífen (`:` → `-`), mas para assinatura o SDK aceita qualquer forma: `A:B`, `A-B` (qualquer ordem) ou apenas o ID do usuário destinatário — todos canonizam para os mesmos bytes assinados |

### A API retorna 400 para uma chamada que muda estado

Toda chamada de chat que muda estado — adicionar ou rotacionar chaves de conversa, criar um grupo, adicionar membros — requer **`action_signatures`** no corpo da requisição, validado na borda da API. Uma entrada ausente ou malformada (cada uma precisa de `message_id`, `encoded_message_event_detail` e um `message_event_signature` com `signature`, `public_key_version` e `signature_version`) retorna uma resposta problem-details HTTP 400 imediatamente. Use os métodos prepare do SDK (`prepare_conversation_key_change`, `prepare_group_create`, `prepare_group_members_change`) e envie **todas** as assinaturas retornadas — criação de grupo e adição de membros retornam duas.

***

## Criptografia e descriptografia de mídia

* Use a **mesma** chave de conversa (e versão) da mensagem que referencia o anexo
* Trate respostas de download como **texto cifrado** até executar `decrypt_stream`
* Infira o tipo MIME **após** descriptografar; o `Content-Type` do download frequentemente não é o tipo real da imagem

Detalhes: [Mídia](/pt/xchat/media).

***

## Depuração segura

Ao investigar falhas de criptografia:

* Registre apenas IDs de conversa, IDs de evento e **versões** de chave
* **Não** registre texto simples, códigos de acesso, chaves privadas ou blobs de chave completos
* Confirme que a versão de chave de assinatura passada para `set_identity` corresponde ao `public_key_version` do seu registro de chave pública
* Para histórico incompleto, pagine **todas** as páginas de eventos para que metadados de mudança de chave não sejam pulados antes de descriptografar
