Qué hacer con un reporte de bug que no puedes reproducir

reportes de bugs

El reporte está en tu tracker. El usuario vio cómo pasaba, y le crees, pero en tu máquina todo funciona y ya has gastado una hora en demostrarlo. ¿Y ahora qué?

La mayoría de los equipos tiene una sola jugada aquí: etiquetarlo como «no se puede reproducir» y cerrarlo. Esa jugada te cuesta el doble sin que se note. El bug se queda en producción, donde lo encontrarán tus próximos usuarios. Y quien lo reportó aprende que reportar bugs no sirve de nada, así que el siguiente reporte, el que traería el detalle que habría resuelto este, nunca se envía.

Diagnosticar por qué un bug se reproduce en su máquina y no en la tuya es una disciplina aparte: la diferencia siempre está en algún punto del estado, los tiempos, el entorno o los datos. Este artículo trata de la otra mitad del trabajo: el flujo. Qué haces con el ticket, hoy, cuando la reproducción ha fallado.

Cambia «cerrado» por una decisión de verdad

Un reporte que no se reproduce tiene tres desenlaces honestos, y «cerrado» no es uno de ellos:

  1. Corregido de todos modos: la evidencia apuntaba a una causa que pudiste corregir sin llegar a ver el bug en vivo.

  2. Aparcado con instrumentación: no lograste resolverlo, así que dejaste una trampa para la próxima vez y seguiste adelante.

  3. En observación: el reporte es un dato aislado; esperas a propósito a que llegue un segundo.

Cada uno de los pasos que siguen alimenta uno de esos tres desenlaces. El objetivo del triaje no es reproducir: es llevar el ticket a una decisión que puedas defender.

Paso 1: exprime el reporte que tienes

Antes de tocar un navegador, saca todo lo que el reporte contiene de verdad:

  • Cruza la marca de tiempo. Compara la hora del reporte con los logs del servidor y con el historial de despliegues. «Se rompió a las 14:02» al lado de «desplegamos a las 13:58» ha resuelto más misterios que cualquier depurador.

  • Busca reportes hermanos. La misma página, el mismo texto de error, el mismo endpoint, en tu tracker y en tu monitorización de errores. Un reporte que parece único suele ser el tercero de su clase con tres títulos distintos.

  • Lee el síntoma al revés. Si el botón «no hizo nada», enumera lo que puede tragarse un clic: un estado deshabilitado, un return prematuro, una promesa rechazada sin manejar. Cada hipótesis implica una condición en la que pudo estar el usuario. Todavía no estás reproduciendo: estás armando una lista corta.

Paso 2: reprodúcelo como el usuario, con una hora de límite

Los intentos de reproducción fallan porque los desarrolladores reproducen como ellos mismos: sesión nueva, red rápida, cuenta de admin, pantalla grande. Dedica una hora, y solo una, a ser a propósito quien reportó. Su navegador y su tipo de dispositivo, su viewport, una conexión limitada, una cuenta con su rol y su volumen de datos, su secuencia de acciones en lugar de la sensata.

Si la hora no da nada, para. Las cacerías de reproducción sin límite son la forma en que un bug mediano se come un sprint. En los dos casos, el procedimiento continúa.

Paso 3: hazle a quien reportó una pregunta, no cinco

Un cuestionario se abandona; una sola pregunta concreta se responde. Elige aquella cuya respuesta parte tu lista corta por la mitad («¿sigue pasando después de recargar?», «¿pasa siempre con el mismo registro?») y envía solo esa.

Una regla más: pide hechos, nunca trabajo. «¿Qué navegador?» es un dato que los usuarios no pueden darte de forma fiable y que una herramienta captura automáticamente; preguntarlo gasta la buena voluntad de quien reporta en algo que debería haber hecho una etiqueta script.

Paso 4: aparca el ticket como es debido

Aparcar no es cerrar. Un ticket bien aparcado tiene tres cosas:

  • La evidencia adjunta: todo lo del paso 1, más las hipótesis que descartaste, para que nadie repita la misma hora el mes que viene.

  • Una trampa puesta: añade la línea de log, el breadcrumb o la aserción que saltará cuando vuelva a pasar. Si tu herramienta de reportes captura la salida de la consola, un console.error bien colocado en el código sospechoso convierte el siguiente reporte en el diagnóstico.

  • Un disparador de recurrencia: el ticket se reabre cuando llega un reporte hermano, en lugar de depender de que alguien recuerde que existe.

Paso 5: trata el segundo reporte como la pista clave del caso

Los bugs que no se reproducen vuelven: es lo único fiable que tienen. Y el segundo reporte cambia las reglas: un reporte es una anécdota, dos son una comparación, cinco son un conjunto de datos. Pregúntate qué comparten las apariciones (¿navegador?, ¿rol?, ¿un registro concreto?, ¿hora del día?) y qué no. Las variables compartidas son tu causa; el resto es ruido.

Por eso los reportes duplicados deberían acumularse en una sola tarea en lugar de cerrarse como duplicados: justo en este tipo de bug, la pila es el análisis. También es un punto donde un asistente de IA ayuda de verdad: conectados a tus reportes a través del servidor MCP de BugDump, Claude Code o Cursor recorren todos los reportes de una tarea y encuentran el hilo común más rápido que una persona revisando cinco repeticiones de sesión.

Mantén informado a quien reportó

Dos frases, en dos momentos: cuando lo aparcas («todavía no hemos dado con la causa; hemos añadido monitorización y tu reporte sigue abierto») y cuando está corregido («tu reporte de marzo fue la clave para resolverlo, gracias»). La primera conserva la relación; la segunda es la inversión más barata que existe en cultura de reporte. Quien ve que sus reportes importan escribe reportes mejores.

Arregla el flujo de reportes, no solo el bug

Todo lo que este procedimiento intenta sortear (el entorno que falta, la secuencia que falta, los errores que faltan) existía en el navegador de quien reportó en el momento del fallo. Solo que no se capturó. Esa es la solución duradera: cuando un reporte se envía desde BugDump, llega con el buffer de la consola (con los errores marcados), las peticiones de red recientes (con los fallos resaltados), navegador, sistema operativo, dispositivo, viewport, URL de la página y una repetición de sesión, que puedes recorrer, de lo que hizo de verdad el usuario. Añade una llamada a identify y sabrás qué cuenta revisar en lugar de adivinar una parecida.

Con ese flujo en marcha, la mayor parte de este procedimiento deja de hacer falta: el paso 1 ya viene hecho, el paso 2 parte de hechos y la pregunta del paso 3 suele estar ya respondida. El «no se puede reproducir» no desaparece del todo, pero deja de ser una resolución y se convierte en lo que siempre debió ser: un estado raro y temporal entre un reporte y una corrección.

Te puede interesar