Referência
Códigos de erro Catálogo completo dos códigos tipados retornados pela API, por módulo.
A API retorna erros como { "error": "CODIGO_TIPADO" } em todos os 4xx. Esta página é o catálogo canônico — clientes devem comparar pelo código, nunca pela mensagem.
Convenção e padrão completo em Convenções de erro . Cada controller mapeia código → status HTTP via STATUS_BY_CODE.
Código Status Onde acontece Causa Como resolver EMAIL_ALREADY_EXISTS409 POST /auth/registerE-mail já cadastrado Use login ou recovery INVALID_CREDENTIALS401 POST /auth/login, PUT /auth/change-passwordEmail/senha não bateu, ou senha atual incorreta Verificar credenciais; se persistir, usar reset INVALID_RESET_TOKEN400 POST /auth/reset-passwordToken expirado/usado/inexistente Solicitar novo via /forgot-password PASSWORD_ALREADY_SET409 POST /auth/set-passwordUser já tem senha local Use change-password USER_NOT_FOUND404 Várias User do JWT não existe (conta deletada com sessão viva) Logout + re-login GOOGLE_ALREADY_LINKED_TO_OTHER_USER400 GET /auth/google/linkGoogle account já é vínculo de outra conta Desvincule da outra conta primeiro GOOGLE_NOT_LINKED404 DELETE /auth/google/linkConta atual não tem Google — PASSWORD_REQUIRED_BEFORE_UNLINK409 DELETE /auth/google/linkSem senha local; desvincular deixaria orfã Use set-password antes INVALID_STATE (redirect)— GET /auth/google/callbackState JWT inválido/expirado Refazer fluxo OAUTH_FAILED (redirect)— GET /auth/google/callbackToken exchange/userInfo falhou Tentar de novo EMAIL_MISSING (redirect)— GET /auth/google/callbackConta Google sem e-mail Re-autorizar com escopo email LOGIN_FAILED / LINK_FAILED (redirect)— GET /auth/google/callbackErro inesperado Logs do backend
Código Status Causa Como resolver USER_NOT_FOUND404 User não existe — FORBIDDEN403 Tentativa de editar perfil/recurso de outro user — STORAGE_NOT_CONFIGURED500 S3Adapter sem credenciais válidas Configurar .env
Validação Zod (updateProfileSchema, etc.) retorna 400 com detalhes em .flatten().
Código Status Causa Como resolver SELF_REQUEST400 Tentou pedir amizade pra si mesmo — SELF_BLOCK400 Tentou se bloquear — ALREADY_EXISTS409 Pedido pendente já existe nessa direção — NOT_FOUND404 Friendship/block não existe — NOT_PENDING409 Tentou aceitar/rejeitar pedido que já foi processado Re-fetch a lista FORBIDDEN403 Tentou aceitar/cancelar pedido de outro user —
Código Status Causa Como resolver NOT_FOUND404 Coleção não existe — FORBIDDEN403 Não é dono da coleção — INVALID_NAME400 Nome vazio/excede 100 chars — FIELD_IN_USE409 Tentou remover do schema field que items já usam Considerar is_hidden em vez FIELD_NOT_FOUND404 field_definition_id inválido no schema —
Código Status Causa Como resolver NOT_FOUND404 Item não existe — FORBIDDEN403 Não é dono — REQUIRED_FIELD_MISSING422 Field marcado isRequired no schema não foi preenchido Preencher campo INVALID_FIELD_TYPE422 Tipo do valor não bate com fieldType (ex: string em number) Coercion no client INVALID_FIELD_VALUE422 Valor não está em selectOptions (para tipo select) Use uma das opções INVALID_RATING422 Rating fora de 1-5 — CANNOT_EDIT_ITEM_SHARE403 Tentou editar post auto-criado de tipo item_share Edita o item; post é auto-derived
Código Status Causa Como resolver FIELD_KEY_ALREADY_EXISTS409 Tentou criar definition custom com field_key que já existe Use outro nome FIELD_KEY_DUPLICATE409 Mesmo conflito (variante em outro path) — SYSTEM_FIELD_LOCKED403 Tentou deletar/editar definition de sistema Não permitido; use is_hidden NOT_FOUND404 — —
Código Status Causa Como resolver ITEM_NOT_FOUND404 Item alvo não existe — NOT_FOUND404 Listing não existe — NOT_AUTHORIZED403 Não é dono do listing — ALREADY_LISTED409 Item já tem listing active Encerrar o existente OU editar INVALID_TRANSITION422 Tentou pause/resume em estado errado (ex: pause de closed) Verifique estado LISTING_CLOSED422 Tentou editar/pausar/reativar listing closed Listing terminou ciclo LISTING_NOT_CLOSED422 Tentou hard delete sem ter encerrado antes DELETE encerra; com ?hard=true em closed faz hard delete
Código Status Causa Como resolver LISTING_NOT_FOUND404 listingId no body inválido — LISTING_NOT_ACTIVE409 Listing pausado/closed Não aceita ofertas ITEM_NOT_FOUND404 Item alvo desapareceu — OFFER_NOT_FOUND404 offerId inexistente — OFFERED_ITEM_NOT_FOUND404 offered_item_id em trade não existe — OFFERED_ITEM_NOT_OWNED403 Tentou oferecer item que não é seu — OFFERED_COLLECTION_PRIVATE422 Item oferecido está em coleção private — owner não consegue verificar Mudar visibility da coleção OFFERED_COLLECTION_REQUIRES_FRIENDSHIP403 Coleção friends_only entre não-amigos Adicionar amizade ITEM_NOT_AVAILABLE404 Item já transferido — ITEM_NOT_FOR_SALE / ITEM_NOT_FOR_TRADE422 Listing não suporta tipo da oferta — CANNOT_OFFER_OWN_ITEM403 Owner tentou ofertar pro próprio listing — DUPLICATE_PENDING_OFFER409 Já tem oferta pending nesse item Cancelar a antiga primeiro NO_PENDING_PROPOSAL409 Tentou accept/reject sem proposal pending Re-fetch CANNOT_ACCEPT_OWN_PROPOSAL / CANNOT_REJECT_OWN_PROPOSAL403 Tentou agir na própria proposal (precisa ser do oposto) Esperar oposto ALREADY_PROPOSED409 Já tem proposal pending — não pode criar outra — OFFER_NOT_NEGOTIABLE409 Oferta em estado final (completed, cancelled, rejected) — INVALID_PROPOSAL422 Counter-proposta inválida (ex: trade sem offered_item_id) — NO_PROPOSAL_HISTORY404 Histórico vazio (impossível na prática) — NOT_AUTHORIZED403 Não é offerer nem owner — INVALID_TRANSITION409 Tentou ação não permitida no estado atual — ALREADY_CONFIRMED409 Lado já confirmou (mas confirm é idempotente) ITEM_GONE / OFFERED_ITEM_GONE410 Item foi deletado entre create e confirm Cancelar oferta OFFERER_HAS_NO_COLLECTION / OWNER_HAS_NO_COLLECTION422 Receptor não tem coleção compatível pra acolher transfer Backend tenta auto-criar; se falhar, criar manualmente
Código Status Causa Como resolver OFFER_NOT_FOUND / NOT_FOUND404 offerId inválido — OFFER_NOT_COMPLETED422 Tentou avaliar offer não-completed Esperar transferência confirmar NOT_AUTHORIZED403 Não é participante (offerer/owner) — WINDOW_EXPIRED422 Mais de 30 dias após completed Janela fechou ALREADY_RATED409 Já avaliou essa oferta (unique offer×rater) Imutável — não dá pra refazer
Código Status Causa Como resolver NOT_FOUND404 Conversation/message/dm_request inexistente — FORBIDDEN403 Não é membro / sem role suficiente — NOT_FRIEND400 Tentou abrir DM com não-amigo Use DM request BLOCKED403 Há block em alguma direção — MEDIA_LIMIT_EXCEEDED413 Attachment excede 5MB ou >10 arquivos —
Código Status Causa Como resolver TARGET_NOT_FOUND404 targetId não existe pro targetType — ALREADY_REPORTED409 Já denunciou esse target — CANNOT_REPORT_OWN403 Tentou denunciar próprio conteúdo —
Código Status Causa Como resolver USER_NOT_FOUND404 — — STEAM_NOT_LINKED400 Tentou usar API sem vincular conta POST /integrations/steam/loginSTEAM_API_KEY_MISSING400 Sem users.steam_api_key PUT /integrations/steam/api-keySTEAM_API_KEY_INVALID_FORMAT422 Key não tem 32 chars hex Verifique no Steam dashboard STEAM_ALREADY_LINKED_TO_OTHER_USER409 Conta Steam já é de outro user — STEAM_REPLACE_REQUIRES_UNLINK409 Tentou vincular outra Steam sem desvincular antes DELETE /integrations/steam/link primeiroSTEAM_PROFILE_PRIVATE422 Steam profile não permite GetOwnedGames Tornar perfil público STEAM_AUTH_FAILED502 Steam API rejeitou (key inválida ou ban temporário) Verificar key IMPORT_NO_GAMES_SELECTED400 appIds vazio Selecione pelo menos 1 IMPORT_DESTINATION_REQUIRED400 Nem collectionId nem newCollectionName Forneça um IMPORT_INVALID_COLLECTION_NAME400 newCollectionName inválido 1-100 chars IMPORT_COLLECTION_NOT_FOUND404 collectionId inválido — IMPORT_COLLECTION_NOT_OWNED403 Coleção é de outro user — IMPORT_COLLECTION_NOT_GAMES_TYPE400 Coleção não é tipo games — IMPORT_ALREADY_IN_PROGRESS409 Há batch ativo do mesmo user Aguardar concluir ou implementar cancel
Código Status Onde NOT_FOUND404 Notification/post/comment inexistente FORBIDDEN403 Não é dono da notification (tentou marcar lida de outro user) SELF_REACTION400 Reagir ao próprio post bloqueado em alguns casos
Toda request com body/query/params inválidos retorna 400 com schema padrão:
{
"statusCode" : 400 ,
"error" : "Bad Request" ,
"message" : "querystring.limit must be number" ,
"code" : "FST_ERR_VALIDATION"
}
Frontend pode parsear message pra mostrar campo específico, ou tratar genérico.
Status Quando 500 Bug no código, problema de DB, integração externa fora 502 Steam API/Google OAuth falhou downstream 503 Manutenção / shutdown gracioso (não implementado hoje)
5xx não devem ter código tipado — são bugs ou indisponibilidades. Logs do backend são fonte da causa raiz.
Adicione no *.controller.ts em STATUS_BY_CODE
Throw ModuleError com o code no service
Documente aqui (PR no docs)
Frontend trata em UI específico se for caso de UX particular (modal, redirect)
Detalhes em Convenções de erro e Tutorial: Adicionar novo endpoint .