Claude Code para fallos de CI: pídele que cite la salida fallida, sugiera el arreglo más pequeño y añada una prueba de regresión para evitar repeticiones.

Un fallo de CI normalmente no es un misterio. El log te dice dónde se detuvo, qué comando falló y el mensaje de error. Una buena ejecución incluye un stack trace, un error del compilador con archivo y número de línea, o un informe de pruebas que muestra qué aserción falló. A veces incluso obtienes una pista tipo diff como "expected X, got Y" o un paso claramente fallido como "lint", "build" o "migrate database".
El problema real es que la gente (y la IA) a menudo trata el log como ruido de fondo. Si pegas un log largo y pides "un arreglo", muchos modelos saltan a una explicación familiar en lugar de leer las últimas líneas significativas. La adivinanza empeora cuando el error parece común ("module not found", "timeout", "permission denied"). Terminas con una reescritura grande, una dependencia nueva o un consejo de "intenta actualizar todo" que no encaja con la falla real.
El objetivo no es "hacer que pase de alguna forma". Es más simple:
En la práctica, el "arreglo mínimo" suele ser una de estas cosas: un cambio de código de unas pocas líneas en un solo lugar, una importación faltante o una ruta incorrecta, un valor de configuración claramente erróneo para el entorno de CI, o revertir un cambio accidental que rompió en vez de rediseñar el código.
Una prueba de seguimiento importa también. Pasar CI una vez no es lo mismo que evitar repeticiones. Si la falla vino de un caso límite (entrada nula, zona horaria, redondeo, permisos), añade una prueba de regresión que falle antes del arreglo y pase después. Eso convierte un rescate puntual en una barrera protectora.
La mayoría de los arreglos malos empiezan con contexto faltante. Si solo pegas la última línea roja, el modelo tiene que adivinar qué pasó antes, y las adivinanzas a menudo se convierten en reescrituras.
Procura dar suficiente detalle para que alguien pueda seguir la falla desde el primer error real hasta el final, y luego cambiar lo menos posible.
Copia esto en tu mensaje (literal cuando puedas):
go test ./..., npm test, flutter test, golangci-lint run).\n- Las rutas de archivo mencionadas en el error, más cualquier configuración relevante (config de tests, config de linter, scripts de build).\n- Qué cambió recientemente: resumen del diff del PR, bumps de dependencias, ediciones de config de CI.\n- Si es intermitente: dos o tres ejecuciones fallidas y una pasada si las tienes.Añade restricciones en palabras claras. Si quieres un arreglo pequeño, dilo: sin refactors, sin cambios de comportamiento salvo que sean necesarios, limita el parche al área que falla.
Un ejemplo simple: CI falla en un paso de lint tras un bump de dependencia. Pega la salida del linter empezando por la primera advertencia, incluye el comando que usó CI y menciona el cambio de versión de un paquete. Eso suele ser suficiente para sugerir una línea de config o un pequeño cambio de código, en vez de reformatear medio repo.
Si quieres algo listo para pegar, esta estructura suele bastar:
CI command:
Failing output (full):
Recent changes:
Constraints (smallest fix, no refactor):
Flaky? (runs attached):
Cuando un modelo falla con una rotura de CI, suele ser porque tu prompt le permite adivinar. Tu trabajo es hacer que muestre su razonamiento usando la salida fallida exacta y luego se comprometa con el cambio mínimo que podría hacer que el job pase.
Exige evidencia y un plan pequeñito. Un buen prompt fuerza cinco cosas:
La incertidumbre está bien. La incertidumbre oculta es lo que hace perder tiempo.
Pega esto al inicio de tu pregunta sobre CI:
Use ONLY the evidence in the CI output below.
1) Quote the exact failing lines you are using.
2) Give ONE sentence: the most likely cause.
3) Propose the smallest fix: 1-3 edits, with file paths.
4) Do NOT do formatting/renames/refactors or "cleanup".
5) List uncertainties + the one extra detail that would confirm the diagnosis.
Si el log dice "expected 200, got 500" junto con un stack trace hacia user_service.go:142, esta estructura empuja la respuesta hacia esa función y a un pequeño guard o manejo de errores, no a rediseñar el endpoint.
Las victorias más rápidas vienen de un prompt que obliga a citar los logs, se mantiene dentro de las restricciones y se detiene cuando falta información.
You are helping me fix a CI failure.
Repo context (short):
- Language/framework:
- Test/build command that failed: <PASTE THE EXACT COMMAND>
- CI environment (OS, Node/Go/Python versions, etc.):
Failing output (verbatim, include the first error and 20 lines above it):
<PASTE LOG>
Constraints:
- Propose the smallest possible code change that makes CI pass.
- Do NOT rewrite/refactor unrelated code.
- Do NOT touch files you do not need for the fix.
- If behavior changes, make it explicit and justify why it is correct.
Stop rule (no guessing):
- If the log is incomplete or you need more info (missing stack trace, config, versions, failing test name), STOP and ask only the minimum questions needed.
Your response format (follow exactly):
1) Evidence: Quote the exact log lines that matter.
2) Hypothesis: Explain the most likely cause in 2-4 sentences.
3) Smallest fix: Describe the minimal change and why it addresses the evidence.
4) Patch: Provide a unified diff.
5) Follow-up: Tell me the exact command(s) to rerun locally to confirm.
Then, write ONE regression test (or tweak an existing one) that would fail before this fix and pass after it, to prevent the same failure class.
- Keep the test focused. No broad test suites.
- If a test is not feasible, explain why and propose the next-best guardrail (lint rule, type check, assertion).
Dos detalles que reducen idas y vueltas:
La forma más rápida de perder tiempo es aceptar un cambio de "limpieza" que modifica cinco cosas a la vez. Define "mínimo" desde el principio: el diff más pequeño que haga pasar el job fallido, con el menor riesgo y la forma más rápida de verificar.
Una regla simple funciona bien: arregla el síntoma primero y luego decide si un refactor más amplio vale la pena. Si el log apunta a un archivo, una función, una importación faltante o un caso límite, ve allí. Evita ediciones de "mientras estamos aquí".
Si realmente necesitas alternativas, pide dos y solo dos: "arreglo mínimo más seguro" vs "arreglo mínimo más rápido". Quieres trade-offs, no un menú.
También exige verificación local que coincida con CI. Pide el mismo comando que ejecuta la pipeline (o el equivalente más cercano), para que puedas confirmar en minutos:
# run the same unit test target CI runs
make test
# or the exact script used in CI
npm test
Si la respuesta sugiere un cambio grande, devuelve con: "Muestra el parche más pequeño que arregla la aserción fallida, sin formateos o renombres no relacionados."
Un arreglo sin prueba es una apuesta a que no volverás a ver el mismo problema. Siempre pide una prueba de regresión que falle antes del parche y pase después.
Sé específico sobre qué es “bueno”:
Un patrón útil requiere cuatro cosas: dónde poner la prueba, cómo nombrarla, qué comportamiento debe cubrir y una breve nota explicando por qué evita futuras regresiones.
Fragmento listo para añadir:
Ejemplo: CI muestra un panic cuando un handler de API recibe un ID vacío. No pidas "una prueba para esta línea". Pide una prueba que cubra IDs inválidos (vacío, espacios, formato incorrecto). El arreglo mínimo puede ser una cláusula de guardia que devuelva 400. La prueba de seguimiento debe asertar comportamientos para múltiples entradas inválidas, de modo que si alguien refactoriza el parsing, CI falle rápidamente.
Si tu proyecto ya tiene convenciones de tests, descríbelas. Si no, pide que la prueba siga tests cercanos en el mismo paquete o carpeta y que sea mínima y legible.
Pega la sección del log de CI que incluye el error y 20–40 líneas por encima. También pega el comando exacto que falló y detalles clave del entorno (SO, versiones del runtime, flags importantes).
Luego pídele que reformule qué falló en palabras sencillas y que señale las líneas del output que lo prueban. Si no puede citar el log, no lo ha leído realmente.
Pide el cambio más pequeño posible que haga que el comando fallido pase. Rechaza refactors. Antes de aplicar nada, que liste:
Aplica el parche y vuelve a ejecutar el comando fallido localmente (o en el mismo job de CI si esa es tu única opción). Si sigue fallando, pega solo la nueva salida fallida y repite. Mantener el contexto pequeño ayuda a mantener la respuesta enfocada.
Una vez verde, añade una prueba de seguimiento enfocada que habría fallado antes del parche y ahora pase. Manténla dirigida: una prueba, una razón.
Vuelve a ejecutar el comando otra vez con la prueba incluida para confirmar que no solo silenciaste el error.
Pide un mensaje de commit corto y una descripción de PR que incluya qué falló, qué cambió, cómo lo verificaste y qué prueba evita la repetición. Los reviewers van más rápido cuando la lógica está explicada.
Un fallo común: todo funciona localmente y luego un cambio pequeño hace que las pruebas fallen en el runner de CI. Aquí hay uno simple de una API en Go donde un handler empezó a aceptar un valor solo de fecha (2026-01-09) pero el código seguía parseando solo timestamps RFC3339 completos.
Este es el tipo de snippet que debes pegar (mantenlo corto, pero incluye la línea de error):
--- FAIL: TestCreateInvoice_DueDate (0.01s)
invoice_test.go:48: expected 201, got 400
invoice_test.go:49: response: {"error":"invalid due_date: parsing time \"2026-01-09\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"\" as \"T\""}
FAIL
exit status 1
FAIL app/api 0.243s
Ahora usa un prompt que obligue a dar evidencia, un arreglo mínimo y una prueba:
You are fixing a CI failure. You MUST use the log to justify every claim.
Context:
- Language: Go
- Failing test: TestCreateInvoice_DueDate
- Log snippet:
<PASTE LOG>
Task:
1) Quote the exact failing line(s) from the log and explain the root cause in 1-2 sentences.
2) Propose the smallest possible code change (one function, one file) to accept both RFC3339 and YYYY-MM-DD.
3) Show the exact patch.
4) Add one regression test that fails before the fix and passes after.
Return your answer with headings: Evidence, Minimal Fix, Patch, Regression Test.
Una buena respuesta señalará la incompatibilidad de layouts de parsing y hará un cambio pequeño en una función (parseDueDate en invoice.go) para intentar RFC3339 primero y caer al formato 2006-01-02. Sin refactor, sin paquetes nuevos.
La prueba de regresión es la barrera: enviar due_date: "2026-01-09" y esperar 201. Si alguien más tarde elimina la caída a ese formato, CI rompe de nuevo con la misma clase de fallo.
La forma más rápida de perder una hora es dar una vista recortada del problema. Los logs de CI son ruidosos, pero la parte útil suele ser 20 líneas por encima del error final.
Una trampa es pegar solo la última línea roja (por ejemplo, "exit 1") ocultando la causa real anterior (una variable de entorno faltante, un snapshot fallido o la primera prueba que se colapsó). Solución: incluye el comando fallido y la ventana de log donde aparece el primer error real.
Otro sumidero de tiempo es dejar que el modelo haga "limpieza" en el proceso. Formateos extra, bumps de dependencias o refactors son más difíciles de revisar y más fáciles de romper. Solución: bloquea el alcance al cambio mínimo y rechaza todo lo no relacionado.
Algunos patrones a vigilar:
Si sospechas intermitencia, no lo tapes con reintentos. Elimina la aleatoriedad (tiempo fijo, seed del RNG, directorios temporales aislados) para que la señal sea clara.
Antes de hacer push, haz una pasada de sanidad corta. El objetivo es comprobar que el cambio es real, mínimo y repetible, no una pasada de suerte.
Finalmente, ejecuta un conjunto un poco más amplio que el job original (por ejemplo, lint + unit tests). Es común arreglar el job que falló y romper otro objetivo.
Si quieres que esto ahorre tiempo semana tras semana, trata tu prompt y la estructura de respuesta como proceso de equipo. La meta es entradas repetibles, salidas repetibles y menos "arreglos misteriosos" que rompan otra cosa.
Convierte tu mejor prompt en un snippet compartido y pégalo en el chat del equipo. El objetivo es formato estándar de respuesta: (1) evidencia, (2) causa en una línea, (3) cambio mínimo, (4) prueba de seguimiento, (5) cómo verificar localmente. Cuando todos usan el mismo formato, las revisiones son más rápidas porque los reviewers saben dónde mirar.
Un bucle ligero que funciona en la mayoría de equipos:
Si prefieres un flujo centrado en chat para construir e iterar en apps, puedes ejecutar el mismo bucle de arreglo y prueba dentro de Koder.ai, usar snapshots mientras experimentas y exportar el código cuando estés listo para mergearlo de vuelta en tu repo.
Empieza por el primer error real, no por el exit 1 final.
Pídele que demuestre que leyó el log.
Usa una restricción como:
Por defecto, el parche más pequeño que haga que el paso fallido tenga éxito.
Eso suele significar:
Evita cambios de “limpieza” hasta que CI esté verde.
Pega suficiente contexto para reproducir el fallo, no solo la última línea roja.
Incluye:
go test ./..., npm test, flutter test, etc.).\n- El log desde la primera línea de error hasta el final.\n- Las rutas de archivo mencionadas en los errores.\n- Qué cambió recientemente (bump de dependencias, edición de config de CI, resumen del PR).\n- Si es intermitente (un par de ejecuciones fallidas y una pasada).Sí — decláralo en lenguaje claro y repítelo.
Ejemplos de restricciones:
Esto mantiene la respuesta enfocada y fácil de revisar.
Arregla el primer fallo real.
Si dudas, pide al modelo que identifique el primer paso que falló en el log y cúmplelo.
Trata la flakiness como una señal para eliminar aleatoriedad, no para añadir reintentos.
Estabilizadores comunes:
Una vez determinista, el “arreglo mínimo” suele ser obvio.
Pide el comando exacto que CI ejecutó y ejecútalo localmente.
Escribe una prueba de regresión enfocada que falle antes del arreglo y pase después.
Buenas opciones:
Si fue una falla de lint/build, el “test” equivalente puede ser endurecer una regla de lint o añadir una comprobación que prevenga el mismo error.
Usa snapshots/rollback para que los experimentos sean reversibles.
Un bucle práctico:
Si trabajas en Koder.ai, las instantáneas te ayudan a iterar sin mezclar ediciones experimentales en el parche final.