Saltar al contenido principal

Diagnóstico

Todo fallo queda registrado. Empiece por la ejecución, no por sus logs.

# Todas las ejecuciones fallidas del último día
curl "https://api.inbox.kobana.com.br/v1/workflow-runs?status=failed&created_at[gte]=2026-09-08T00:00:00Z" \
--cert ./client.crt --key ./client.key -H "Authorization: Bearer $JWT"

# Todo sobre una de ellas
curl "https://api.inbox.kobana.com.br/v1/workflow-runs/$RUN_ID" \
--cert ./client.crt --key ./client.key -H "Authorization: Bearer $JWT"

WorkflowRun.error lista todos los pasos que fallaron, uno por línea, cada uno prefijado con su posición (step 2: …), así que la ejecución ya le dice dónde mirar antes de abrir los pasos.

"El correo se procesó pero no pasó nada en mi sistema"​

Verifique, en este orden:

  1. ¿Hay ejecución? GET /v1/workflow-runs?email_id=…. Si la lista viene vacía, el agente no devolvió workflow — el análisis está en Email.agent_metadata, y el problema es de prompt, no de integración.
  2. ¿Hay una ejecución con summary.total: 0 y error invalid workflow …? El agente emitió algo que no validó. El valor problemático está en definition.
  3. Si no, la ejecución existe y su error nombra el paso que falló.

Catálogo de errores​

errorQué pasóQué hacer
invalid workflow at `0.url`: …El array del agente no validó. No se envió nada.Lea definition. Normalmente falta url, hay un type distinto de request, o una cabecera reservada. Corrija el prompt.
workflow exceeds 20 stepsEl agente produjo más pasos que el tope.Divida el trabajo, o haga que el prompt condense en menos llamadas.
secret `X` is not defined in this workspaceUna referencia ${{secrets.X}} no tiene secret correspondiente. No se envió nada.GET /v1/secrets y compare. Error de tipeo en el prompt, secret eliminado, o el secret vive en otro workspace — nunca se comparten.
\`steps.2.response.body.id\` refers to a step that has not run yetReferencia hacia adelante — un paso que viene después. (Una referencia a un paso que falló o se saltó no hace fallar el paso: queda skipped.)Los pasos solo ven pasos anteriores. Reordene, o corrija el índice.
\`steps.0.response.body.data.id\` could not be resolvedLa ruta no existe en esa respuesta.Mire el response.body del paso 0 — la forma del destino probablemente no es la que supuso el prompt.
\`steps.0.response.body.id\` resolved to nullLa ruta existe pero es nula.Igual que arriba: el destino no devolvió id, normalmente porque la llamada no hizo lo que usted cree.
expected status 201, got 422El destino rechazó el payload.El response.body de ese paso tiene el motivo. Problema de payload — corrija el prompt o el mapeo.
expected status 200, got 401La credencial fue rechazada.Rote con PUT /v1/secrets (misma key). Verifique que last_used_at avanzó — si no avanzó, el paso nunca llegó a usar ese secret.
timeout after 30000msEl destino no respondió en 30s.Problema del destino. La petición pudo haberse procesado igual — trate la operación como desconocida, no como fallida.
expected status 2xx, got 302El destino respondió una redirección.Las redirecciones nunca se siguen — un 302 a un host privado saltaría todas las verificaciones — así que un 3xx es simplemente un status que no coincide. Apunte el paso a la URL final.
url not allowed: private_ipLa URL resuelta apunta a una dirección privada, de loopback, link-local o de metadatos.Esperado para hosts internos: los workflows solo alcanzan la internet pública. Exponga un endpoint, o use un webhook y llámese a sí mismo.
url not allowed: http_not_allowedhttp:// plano fuera de desarrollo.Use https://.
url not allowed: dns_failureEl hostname no resuelve.Error de tipeo, o un nombre que solo resuelve dentro de su red.
unsupported step type `delay` Un paso guardado tiene un tipo que esta versión no ejecuta.Hoy solo existe request.

Leyendo la petición guardada​

Cada paso conserva la petición tal como se envió — después de sustituir los placeholders, con los valores de secrets reemplazados por [REDACTED]:

{
"position": 0,
"status": "failed",
"request": {
"url": "https://erp.example.com/payables",
"headers": { "Authorization": "Bearer [REDACTED]", "content-type": "application/json" },
"body": "{\"supplier\":\"ACME\",\"amount\":1250.5}"
},
"response": {
"status": 422,
"expected_status": 201,
"body": "{\"error\":\"supplier not found\"}"
},
"error": "expected status 201, got 422"
}

Dos campos responden dos preguntas distintas:

  • request en el paso — lo que realmente enviamos. Úselo contra problemas del lado del destino.
  • definition en la ejecución — lo que escribió el agente, con los placeholders sin resolver. Úselo contra problemas de prompt.

[REDACTED] no es una máscara sobre un valor que podríamos mostrarle: el texto original nunca se escribió. No intente recuperar una credencial desde una ejecución.

Status que no son fallos​

SituaciónSignificado
Paso skippedReferencia a un paso que no tuvo éxito (falló o se saltó) — el error dice depends on step N, which did not succeed. Nunca se envió.
Ejecución running por mucho tiempoLa ejecución se interrumpió a mitad (reinicio de worker). No se reintenta, porque algunos pasos pueden haber llegado ya a sus sistemas. Reejecutar es una decisión humana — POST /v1/emails/{id}/reprocess reinicia el pipeline completo, incluida la llamada al agente.
Ejecución pendingEn cola, aún no iniciada. Normal durante unos segundos.
summary.succeeded: 2 con status: failedEl paso 1 falló, el paso 2 dependía de él y se saltó, los pasos 0 y 3 son independientes y salieron bien. Esos dos sí ocurrieron en sus sistemas.

Esa última fila es la que hay que interiorizar: una ejecución fallida no significa que no pasó nada. Los efectos parciales son reales y no hay rollback — los pasos independientes corren aunque otro falle, y un paso solo depende de lo que referencia. Diseñe la cadena de forma que cada paso sea aceptable de ocurrir sin los otros que no referencia (crear, luego adjuntar, luego notificar — no notificar, luego crear).

Vigilarlo de forma continua​

Suscriba un webhook a workflow.run.failed en vez de consultar en bucle:

{
"event": { "slug": "workflow.run.failed" },
"data": {
"workflow_run_id": "9c8b7a65-…",
"summary": { "total": 3, "succeeded": 1, "error": 2 },
"failed_step": 1,
"failed_steps": [1],
"error": "expected status 201, got 422",
"email": { "id": "…", "subject": "…" },
"agent_run": { "id": "…", "llm_model": "…" }
}
}

Las instantáneas de email y agent_run viajan con el evento, así una alerta puede llevar el asunto y el modelo sin una llamada extra.