Kelova Docs

Errores

Formato del error envelope y catálogo de códigos estables

Formato estándar

La mayoría de los endpoints devuelven errores con un código estable y legible por máquina junto al mensaje:

{
  "error": {
    "code": "SOURCE_NOT_FOUND",
    "message": "source not found"
  }
}
  • code — SCREAMING_SNAKE_CASE, estable una vez publicado. Úsalo para lógica condicional en tu integración; nunca hagas switch sobre message.
  • message — texto libre en inglés, pensado para logs, no para mostrar directamente al usuario final.

Un subconjunto de endpoints — POST /agent/query, POST /agents/{id}/query y los endpoints de /tenants/me/mcp/* — todavía responden con el formato heredado, sin code:

{ "error": "missing tenant context" }

Distínguelos por status HTTP y por el texto de error mientras se completa la migración a códigos estables. El resto de esta página documenta el formato con code (mayoría de la superficie).

Status HTTP

StatusSignificado
400Body inválido, campo faltante o valor fuera de rango
401Token ausente, inválido, expirado o revocado
402Límite del plan alcanzado (PLAN_LIMIT_REACHED) — algunos casos, ver abajo
403Sin permiso — rol insuficiente o sin acceso al workspace
404El recurso no existe o no pertenece a tu tenant
409Conflicto — nombre duplicado, sync ya en curso, último admin, etc.
422El archivo se procesó pero no produjo contenido indexable
429Rate limit — reintenta con backoff
500Error interno — reintenta; si persiste, contacta soporte
503Dependencia no configurada en este ambiente (ej. storage u OCR deshabilitados)

Catálogo de códigos

Genéricos (cualquier dominio)

CódigoHTTPCuándo ocurre
INVALID_REQUEST_BODY400El body no es JSON válido
MISSING_FIELDS400Falta un campo requerido
VALIDATION_ERROR400Un campo tiene un valor inválido (ej. nombre demasiado largo)
UNAUTHORIZED401Token ausente o inválido
FORBIDDEN403Rol insuficiente para la operación
NOT_FOUND404Recurso genérico no encontrado
CONFLICT409Conflicto genérico
TOO_MANY_REQUESTS429Rate limit excedido
PLAN_LIMIT_REACHED402Límite de plan alcanzado (fuentes, documentos)
SERVICE_UNAVAILABLE503Dependencia no configurada en este ambiente
INTERNAL_ERROR500Error no esperado del servidor

Auth

CódigoHTTPCuándo ocurre
INVALID_CREDENTIALS401Email o password incorrectos en /auth/login
INCORRECT_PASSWORD401Password actual incorrecto en /auth/change-password
NO_PASSWORD_SET400La cuenta no tiene password establecido todavía
INVALID_OTP401Código OTP inválido o expirado
INVALID_OTP_PURPOSE400purpose no coincide con el flujo (signup/reset/login)
OTP_SEND_FAILED500Falló el envío del email con el código
WEAK_PASSWORD400El password no cumple la política mínima
NO_WORKSPACE_ACCESS403El usuario no pertenece a ningún tenant
TWO_FACTOR_REQUIRED403La cuenta tiene 2FA activo — usa login con password, no OTP directo
EMAIL_ALREADY_REGISTERED409El email ya es admin de otro tenant (signup)
SLUG_ALREADY_IN_USE409El slug de tenant ya existe (signup)
INVALID_SLUG400El slug no cumple el formato (3–63 chars, alfanumérico + guiones)
ACTIVATION_FAILED400 / 500Token de activación inválido, expirado, o fallo al activar

Fuentes (ingestion)

CódigoHTTPCuándo ocurre
SOURCE_NOT_FOUND404La fuente no existe o no pertenece a tu tenant
INVALID_SOURCE_TYPE400source_type fuera del set permitido
SYNC_IN_PROGRESS409Ya hay un sync en curso para esa fuente
FILE_TOO_LARGE400Excede el máximo (50 MB genérico, 20 MB para imágenes)
UNSUPPORTED_FILE_TYPE400MIME type no soportado
FILE_PROCESSING_FAILED422El archivo se procesó pero no produjo chunks indexables

Agentes y canales

CódigoHTTPCuándo ocurre
AGENT_NOT_FOUND404El agente no existe o no pertenece a tu tenant
INVALID_AGENT_CONFIG400Config inválida (status, origen, retención de transcripts, lead email)
CHANNEL_CONNECT_FAILED400Falló la conexión del canal (ej. bot_token de Telegram rechazado)

Tenant / usuarios / perfil

CódigoHTTPCuándo ocurre
USER_NOT_FOUND404El usuario no pertenece al tenant
CANNOT_REMOVE_LAST_ADMIN409La operación dejaría al tenant sin ningún admin
CANNOT_REMOVE_SELF409Un usuario no puede eliminar su propia membership
INVALID_ROLE400El rol no es uno de admin|member|viewer|api_user
MEMBERSHIP_NOT_FOUND404La cuenta no tiene membership en el tenant actual
COMPANY_PROFILE_NOT_FOUND404El tenant no tiene perfil fiscal configurado

Buenas prácticas

  • Trata code como el contrato estable; message puede cambiar sin aviso.
  • Ante 429, respeta un backoff exponencial — no reintentes inmediatamente.
  • Ante 402 PLAN_LIMIT_REACHED en /ingest/sources o /ingest/sources/upload: la operación se rechazó porque ya alcanzaste el límite de fuentes de tu plan. A diferencia de los excesos de documentos o consultas (que se registran y facturan sin bloquear — ver Límites de uso), el límite de fuentes activas sí bloquea la creación de una fuente nueva.

On this page