Pular para o conteúdo principal

Códigos de erro

Todo erro compartilha um envelope: um código legível por máquina, uma mensagem legível por humanos no idioma de quem chama, detalhes por campo para falhas de validação, e um identificador de rastro.

Ramifique pelo código. A mensagem é texto de exibição e pode ser reescrita ou traduzida; o código é um identificador estável.

O envelope

Todo erro que a plataforma devolve tem este formato:

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{ "field": "lei",
"code": "errors.LEI_FORMAT",
"message": "Legal Entity Identifier must be 20 characters",
"ruleType": "regex",
"severity": "error" },
{ "field": "address.state",
"code": "REQUIRED",
"message": "State is required when the country is US",
"ruleType": "cross_field",
"severity": "warning" }
],
"traceId": "550e8400-e29b-41d4-a716-446655440000"
}
}

details é preenchido em falhas de validação e é o que permite a um cliente pôr cada mensagem sob o campo que a causou, em vez de mostrar um único aviso para um formulário com dois problemas. Note que field usa o caminho pontuado para um sub-campo composto — address.state, não state.

Falhas conduzidas por regra carregam ainda ruleType e severity, então um cliente distingue um erro bloqueante de um aviso registrado sem tabela de consulta.

Erros que não são por campo trazem details vazio e dependem do código:

{
"error": {
"code": "ENTITY_ALREADY_MERGED",
"message": "This entity has been merged into another",
"details": [],
"traceId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
}

O traceId é gerado por requisição. Cite-o ao relatar um problema — ele localiza a requisição exata nos logs.

Situações

SituaçãoSignificaFaça
400Requisição malformada ou inválidaCorrija a requisição. details nomeia cada campo problemático.
401Não autenticado, ou sessão revogada (SESSION_REVOKED)Entre novamente. Não há fluxo de renovação.
403Autenticado mas não autorizadoVeja abaixo — a causa difere por código
404Não encontradoO recurso não existe, foi excluído, ou pertence a outra organização
409ConflitoRestrição de unicidade. Mude o valor conflitante.
413Payload grande demaisReduza o corpo da requisição
422Bem formada, mas viola uma regra de negócioLeia a mensagem — ela declara a regra
429Requisições demaisTente de novo após o intervalo indicado
500Falha inesperadaReporte com o identificador de rastro
503Temporariamente indisponívelTente de novo após o intervalo indicado

Distinguindo os 403

Causas diferentes, distinguidas por código:

CódigoCausaRemédio
PERMISSION_DENIEDFalta um código de permissão. A resposta nomeia qual.Conceda-o, ou use um papel que o tenha
ABAC_DENIEDUma política ABAC negou este registro específicoRevise a política — a permissão existe, o registro está fora do escopo
SELF_LOCK_FORBIDDEN, SELF_DELETE_FORBIDDEN, SELF_ROLE_REVOKE_FORBIDDEN, SELF_ROLE_ASSIGN_FORBIDDENProteção contra autoação — você não pode desativar, excluir ou remover papéis de si mesmoPeça a outro administrador
FORBIDDENOutra proteção específica da operaçãoLeia a mensagem

A distinção importa porque as correções não têm relação entre si: uma é mudança de papel, outra é mudança de política, e outra normalmente é "peça a outra pessoa".

Por que 404 e não 403 entre organizações

Um registro de outra organização retorna 404, não 403.

Isso não é ofuscação. O isolamento é aplicado no banco de dados, então a linha é genuinamente invisível para a consulta — a plataforma não olhou, encontrou e recusou. Também significa que identificadores não podem ser sondados para descobrir o que existe em outro lugar.

Detalhe de validação

Um 400 carrega uma entrada por campo problemático, cada uma com o campo, um código e uma mensagem. Exiba-as junto aos seus campos em vez de num aviso único — assim quem chama corrige tudo de uma vez.

Erros de regra de negócio

Um 422 significa que a requisição estava bem formada e ainda assim não é permitida, porque uma regra do domínio a proíbe. Eles carregam códigos específicos:

CódigoLevantado quando
ENTITY_ALREADY_MERGEDConsolidando um registro já consolidado
ENTITY_STATUS_ENGINE_MANAGEDDefinindo situação consolidada diretamente
CONSENT_NOT_WITHDRAWABLERevogando um registro cuja base legal não é consentimento
WITHDRAW_ALREADY_REVOKEDRevogando um registro já revogado
UNSUPPORTED_RULE_CONFIGSalvando uma regra que o motor não consegue honrar
UNSUPPORTED_VALUE_SHAPEGravando um escalar num atributo composto
INVALID_VALUE_TYPEFornecendo um tipo de uso fora da lista vinculada
NO_ACTIVE_MATCH_PROFILEComparando um tipo de entidade sem perfil ativo

Erros de configuração são deliberadamente levantados ao salvar, não silenciosamente na execução. Uma regra que nunca dispara é pior que nenhuma regra, porque parece cobertura.

Contrapressão

CódigoSituaçãoSignifica
TOO_MANY_ROWS400A submissão excede o limite de linhas
PAYLOAD_TOO_LARGE413O corpo excede o limite de tamanho
QUEUE_LIMIT_EXCEEDED429A profundidade de fila da organização foi atingida
PAYLOAD_QUOTA_EXCEEDED429A cota de payload foi atingida
RATE_LIMITED429Quem chama excedeu seu limite de taxa
QUEUE_SATURATED503A plataforma está saturada

429 e 503 carregam um intervalo de nova tentativa. Respeite-o. Veja limites para os valores.

Identificadores de rastro

Todo erro carrega um. Ele localiza a requisição nos logs diretamente, o que é muito mais rápido que reconstruir a partir de uma descrição.

Exponha-o nas suas próprias interfaces. Um erro que um usuário consegue reportar por identificador é diagnosticável; um descrito de memória normalmente não é.

Um 500 é sempre um defeito

Todo erro que quem chama consegue causar deveria ser um 4xx com código significativo. Um 500 significa que um caso não tratado chegou à superfície. Reporte com o identificador de rastro em vez de contornar — a correção é mapear o erro.

A seguir


Última verificação no commit d3c2586b (2026-08-03)