Abrí cleyvin.dev para revisar un cambio menor y me encontré con una pantalla en blanco. No un error, no un stack trace — blanco. El tipo de blanco que te hace dudar de si el dominio sigue siendo tuyo.
El síntoma
El HTML llegaba bien. Un curl a la raíz devolvía el documento completo, con sus etiquetas script y link. Pero cada uno de esos recursos —los chunks de JS y CSS que Next genera con un hash en el nombre— devolvía 500. El navegador descargaba un esqueleto perfecto y después no podía vestirlo.
El stack
cleyvin.dev corre como un build standalone de Next, detrás de un systemd unit (cleyvinos-web) que arranca node .next/standalone/server.js en 127.0.0.1:3000, con un túnel de Cloudflare por delante. Nada de Vercel: todo vive en mi servidor.
La pieza clave para entender el bug es esta: el proceso sirve el build que tenía cargado cuando arrancó. El manifiesto de chunks —qué hash le toca a cada archivo— queda en memoria. No se relee del disco en cada request.
La causa raíz
Yo había corrido un pnpm build nuevo sin reiniciar el servicio. Y antes de eso, un pnpm dev había escrito en el mismo directorio .next/.
Resultado: el proceso en memoria seguía anunciando en el HTML los hashes del build viejo, pero en el disco esos archivos ya no existían —el build nuevo los había reemplazado por otros con hashes distintos. El servidor recibía un pedido por un chunk, no lo encontraba, y respondía 500.
HTML del build A + chunks del build B = un sitio que se sirve a sí mismo en ruinas.
La regla que saqué de ahí
Un build de Next standalone no es una carpeta que puedes editar en caliente. Es un artefacto inmutable. El proceso y el contenido de .next/ tienen que estar siempre en sync, y la única forma de garantizarlo es tratar el redeploy como una operación atómica:
rm -rf .next pnpm build sudo systemctl restart cleyvinos-web
El rm -rf .next no es paranoia. Es lo que evita que un build quede contaminado con restos de un pnpm dev anterior. Construyes limpio, y reinicias para que el proceso cargue exactamente lo que hay en disco.
Lo que de verdad aprendí
El bug no era de Next. Era mío: estaba tratando un artefacto de deploy como si fuera un directorio de trabajo. La separación entre lo que estoy editando y lo que está sirviendo producción tiene que ser física, no mental.
Desde entonces el redeploy de cleyvin.dev es siempre esos tres comandos, en ese orden, sin atajos. Y lo dejé escrito en el AGENTS.md del repo para no volver a caer —y para que el próximo que toque esto, humano o agente, lo lea antes de improvisar.