# Códigos de error: Veredictos de sesión

> Cada petición con un JWT que trae `jti` se compara contra `auth_sessions` (`src/auth/sessions/auth-sessions.service.ts`). Siempre encendido, sin variable ni modos desde el 2026-10-05: un veredicto que no pasa responde 401 con el veredicto en `code` (`SESSION_REVOKED`…) y un `message` en español para la persona («Tu sesión venció. Vuelve a iniciar sesión.»); hasta el 2026-10-21 el mensaje era `Session rejected: <código>`. `LEGACY_TOKEN` (token sin `jti`) deja pasar.

**Cómo se detecta (toda la familia):** El front recibe 401 con `code: "<CÓDIGO>"` (DevTools → Red → Respuesta) y manda a iniciar sesión. En Render el 401 se ve en el log de peticiones, sin el código: el rechazo no deja línea propia en el log de la aplicación (la línea `auth.session_check` era del modo `shadow` y se retiró el 2026-10-05). Un fallo de la base sí deja `auth_sessions.<operación> falló (<código del driver>)`, una línea por minuto.

**Qué hacer (toda la familia):** Para la persona: volver a iniciar sesión. Si muchas personas caen a la vez con el mismo código, es un problema del servidor (versión de permisos, base caída), no de ellas: ver la ficha.

Lo que un código no dice lo hereda de la familia.

## `LEGACY_TOKEN`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** El token no trae `jti` (se emitió antes de las sesiones): se acepta hasta que vence. No es un error.

## `SESSION_CHECK_FAILED`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** No se pudo consultar la sesión (la base falló). La petición se niega: falla cerrado.
- **Causa típica:** Base caída o lenta en ese momento.
- **Cómo detectarlo:** Render: `auth_sessions.check falló (<código del driver>)` (una línea por minuto) y, cerca, errores de la base. Si son muchas personas a la vez, es del servidor.
- **Qué hacer:** Revisar la base de datos; las personas pueden reintentar cuando vuelva.

## `SESSION_CLAIMS_INVALID`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** El token trae `jti` o `sv` con forma inválida.

## `SESSION_EXPIRED`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** La sesión venció en `auth_sessions` aunque el JWT siga vivo.

## `SESSION_NOT_FOUND`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** El `jti` del token no existe en `auth_sessions`: la sesión nunca se abrió en esta base o se borró.

## `SESSION_REVOKED`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** La sesión fue cerrada (cerrar sesión, cambio de contraseña o revocación por plataforma).
- **Qué hacer:** La persona vuelve a iniciar sesión. Si fue una revocación masiva, es lo esperado.

## `SESSION_USER_MISMATCH`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** La sesión del `jti` es de otro usuario que el del token. No debería pasar: revisarlo como posible token alterado.

## `SESSION_VERSION_STALE`

- **Tipo:** sesión · **HTTP:** — · **Estado:** vigente
- **Qué significa:** Cambiaron los permisos de la persona (versión en `authz_versions`) después de abrir la sesión: el token ya no representa sus permisos.
- **Causa típica:** Alguien cambió el rol o los permisos de esa persona o de su rol.
- **Qué hacer:** Volver a iniciar sesión para recibir un token con los permisos nuevos. Si le pasa a todos a la vez tras un cambio de roles, es lo esperado.
