# Diagnósticos (referencia DIAG_*)

Cada código DIAG_* que AfterPack emite, qué lo desencadena, cómo resolverlo, y los códigos de salida que devuelve un build.

Source: https://www.afterpack.dev/es/docs/diagnostics

AfterPack nunca entrega una protección más débil de la que pediste. Cuando algo no se puede resolver automáticamente, el build se detiene con un código `DIAG_*` con nombre y una solución específica.

## Niveles de severidad

Cada diagnóstico que emite AfterPack tiene exactamente una de tres severidades. No existe la severidad `Warning`.

| Severidad | Significado | Qué ocurre |
|---|---|---|
| **Info** | Comportamiento esperado: ya reconociste esto, o el motor tomó un mecanismo de reserva seguro que preserva la corrección. | El build tiene éxito, se escribe la salida. |
| **Error** | Tus requisitos declarados no se pueden cumplir sin un cambio de tu parte (un límite de tamaño demasiado estricto, un error de parseo, una clave inválida). | Salida distinta de cero, **no se escribe salida**. |
| **Critical** | Un error del motor. Ninguna acción de tu parte lo arregla. | Salida distinta de cero, no se escribe salida, siempre. [Envía un reporte.](mailto:security@afterpack.dev) |

## Códigos de salida

`npx afterpack@latest` devuelve uno de ocho códigos. Escribe scripts que verifiquen estos códigos directamente.

| Código | Significado |
|---|---|
| `0` | Éxito. Todos los archivos recopilados se ofuscaron y se escribieron. `--help` y `--version` también salen con `0`. |
| `1` | Fallo. No se produjo salida utilizable, y un mensaje en stderr indica qué ocurrió. |
| `2` | Parcial. Reservado para un build con la cuota agotada; hoy ningún build lo devuelve. |
| `3` | Límite de tamaño. La salida alcanzaría el [`inflation.max`](https://www.afterpack.dev/es/docs/config#inflation-max) que estableciste (`DIAG_SIZE_CAP_REACHED`). |
| `4` | Pro necesario. Una entrada de [`regions`](https://www.afterpack.dev/es/docs/config#regions) eleva la protección por encima de la configuración del programa y necesita una [`key`](https://www.afterpack.dev/es/docs/config#key) (`DIAG_PRO_DIRECTIVE_REQUIRES_KEY`). La CLI no lee directivas del código fuente, así que solo `regions` llega a esta salida. |
| `5` | Reflexión. Se detectó un patrón de reflexión en tiempo de ejecución sin [`reflection.allow`](https://www.afterpack.dev/es/docs/config#reflection-allow) (`DIAG_REFLECTION_NOT_ACKNOWLEDGED`). |
| `6` | Actualización necesaria. La nube de AfterPack, o este `afterpack`, necesita un `@afterpack/core` más reciente. No se escribió nada. |
| `64` | Uso incorrecto. Un flag o comando desconocido, un valor malformado, o un argumento de ruta duplicado. |

### Qué hace que un build salga con 64

Los problemas de uso detienen la ejecución antes de que comience.

- Un flag desconocido, un comando desconocido, un valor malformado, o más de una ruta posicional. La línea de uso se reimprime junto con el error.

### Qué hace que un build salga con 1

- Ningún argumento `<path>` y no se encontró salida de build (`dist/`, `build/`, `out/`, `.output/`, `.next/`, o el directorio convencional del bundler indicado en `package.json`). AfterPack nunca lee el archivo de configuración propio de un bundler, así que un directorio de salida personalizado no se detecta de esta forma.
- El directorio de build no existe, o no contiene archivos `.js`/`.mjs`/`.cjs`. Un directorio de build vacío hace fallar el build. La causa habitual es apuntar al directorio equivocado o ejecutar antes del build.
- Un archivo falló directamente, o regresó con salida vacía cuando la entrada no estaba vacía.
- Un archivo que el motor no puede ofuscar de forma segura. El build falla e indica los archivos afectados. Usa [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude) para dejar fuera un archivo que deba entregarse sin tocar.
- Un `verify` fallido o un escaneo `audit` fallido.
- Cualquier código de abajo con severidad `Error` o `Critical`, salvo `DIAG_SIZE_CAP_REACHED` (sale con `3`), `DIAG_PRO_DIRECTIVE_REQUIRES_KEY` (sale con `4`) y `DIAG_REFLECTION_NOT_ACKNOWLEDGED` (sale con `5`).

### Falla de forma segura, sin excepciones

Un build Pro entrega protección de nivel Pro, o no entrega nada.

*(fail-closed request-flow diagram — see the web page)*

Una vez que se resuelve una [`key`](https://www.afterpack.dev/es/docs/config#key), desde [`AFTERPACK_key`](https://www.afterpack.dev/es/docs/config#key) o `afterpack.json`, el build es un build en la nube. Si la llamada a la nube falla por cualquier razón, el motor devuelve un error y el build sale con `1`, o con `6` cuando la nube necesita un `@afterpack/core` más reciente. No recurre a un build local, y no emite salida sin ofuscar. No existe ningún flag que entregue salida sin ofuscar. Detener el build pone el problema donde puedas verlo.

Este contrato no cambia según la vía de invocación: `npx afterpack@latest` y la ejecución automática de un plugin al cerrar el bundle se comportan de forma idéntica.

### Códigos de salida en CI

```bash
npx afterpack@latest dist/ || {
  echo "AfterPack failed: nothing shipped. See the error above."
  exit 1
}
```

Un valor distinto de cero detiene el pipeline. La razón aparece en stderr y en los códigos de abajo.

## Referencia completa

### Motor

| Código | Significado |
|---|---|
| `DIAG_TARGET_REACHED` | Info. Cada parte del archivo alcanzó la [`complexity`](https://www.afterpack.dev/es/docs/config#complexity) solicitada. |
| `DIAG_TARGET_NOT_REACHED` | A partir del motor 0.2.3, Error, y no se escribe salida: una parte de un archivo no puede alcanzar el objetivo de [`complexity`](https://www.afterpack.dev/es/docs/config#complexity) con las transformaciones que permitiste, porque [`transforms.scopeDeepen.enabled`](https://www.afterpack.dev/es/docs/config#transforms-kind-enabled) es `false` o una [directiva de región](https://www.afterpack.dev/es/docs/directives#what-you-can-set) limita esas líneas. El mensaje nombra el archivo y las líneas. Vuelve a activar la transformación, baja `complexity` para ese archivo o región, o excluye el archivo con [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude). En el motor 0.2.2 era Info: el build entregaba una salida menos profunda, y un déficit causado por una transformación desactivada podía informarse como `DIAG_TARGET_REACHED`. |
| `DIAG_INFLATION_BUDGET_HIT` | Info. Solo en un build sin floor con un [`inflation.max`](https://www.afterpack.dev/es/docs/config#inflation-max) finito: una etapa que agrega tamaño se detuvo en ese presupuesto antes de alcanzar el objetivo. La salida es válida. A partir del motor 0.2.3, el floor de constantes de cadena nunca cede al presupuesto, así que en un build con floor este código nunca aparece ni significa que un literal de cadena quedara legible. En el motor 0.2.2, un `inflation.max` explícito también podía cortar la codificación de cadenas; si estableciste uno, vuelve a hacer el build con el motor 0.2.3. |
| `DIAG_SIZE_CAP_REACHED` | Error, código de salida `3`, y no se escribe salida: la salida alcanzaría el [`inflation.max`](https://www.afterpack.dev/es/docs/config#inflation-max) que estableciste. A partir del motor 0.2.3, también se comprueba el archivo terminado contra ese límite, el mensaje nombra ambos tamaños en bytes y la codificación de cadenas nunca se corta para que quepa. Sube `inflation.max`, baja [`complexity`](https://www.afterpack.dev/es/docs/config#complexity) o excluye el archivo con [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude). |
| `DIAG_SELF_INTEGRITY_INERT` | Error, a partir del motor 0.2.3, solo en Pro, y no se escribe salida: [`transforms.selfIntegrity.enabled`](https://www.afterpack.dev/es/docs/config#transforms-kind-enabled) está activado, pero el build no tiene código en `medium` o superior con `transforms.crossDependency.enabled` activado al que adjuntarse. Sube el preset, o una región, a `medium`, vuelve a activar `crossDependency` o desactiva `selfIntegrity`. En el motor 0.2.2 un build así terminaba con éxito sin la comprobación de integridad. |
| `DIAG_PATH_EXCLUDED` | Info. Un archivo coincidió con [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude) y se entregó byte por byte; sus bytes se cuentan como excluidos por el usuario. |
| `DIAG_DYNAMIC_SCOPE_NATIVE` | Info, a partir del motor 0.2.3. Una sentencia `with` o un `eval` directo dejó los ámbitos que lo rodean tal como están escritos: los nombres de cada ámbito que lo contiene, hasta el nivel superior del archivo, conservan su forma original, y las variables globales dentro del cuerpo de un `with` se dejan tal como están escritas. El resto del archivo se ofusca como siempre. Para proteger esos nombres, llama a `eval` de forma indirecta, `(0, eval)(code)`, si el código evaluado no necesita variables locales, o mueve el código que necesita `eval` o `with` a un archivo propio. Consulta [Contrato semántico](https://www.afterpack.dev/es/docs/semantic-contract#what-stays-as-you-wrote-it). |
| `DIAG_SURVIVING_READABLE_LITERAL` | Quedan más literales de string legibles de los que permite [`strings.leaks.max`](https://www.afterpack.dev/es/docs/config#strings-leaks-max). Sube [`complexity`](https://www.afterpack.dev/es/docs/config#complexity), baja [`strings.minLength`](https://www.afterpack.dev/es/docs/config#strings-minLength), o sube el límite. |
| `DIAG_SOURCE_MAP_INTEGRITY` | Info. Un `.map` de origen suministrado falló la validación contra su entrada, así que el mapa de ese archivo se descarta y el código ofuscado se entrega igualmente. Un mapa ausente es inocuo; entregar uno equivocado es el daño que esto evita. |
| `DIAG_OUTPUT_UNPARSEABLE` | Error, y una señal de un error del motor. Volver a parsear la salida falló, así que el build falla de forma segura para ese archivo: sin código, sin mapa de origen, sin Protection Map. |
| `DIAG_PARSE_ERROR` | Error. Un fragmento de entrada no se pudo parsear. AfterPack se ejecuta estrictamente después del build, sobre el JavaScript emitido: compila primero, y luego apúntalo a la salida JS. |
| `DIAG_CONFIG_PARSE_ERROR` | Error. El JSON de la [configuración del motor](https://www.afterpack.dev/es/docs/config) no se pudo deserializar. |
| `DIAG_PRO_DIRECTIVE_REQUIRES_KEY` | Error, salida `4`, y no se escribe salida: un build Free encontró una [directiva de región](https://www.afterpack.dev/es/docs/directives#free-builds) que aumenta la protección por encima de la configuración del programa. Establece una [`key`](https://www.afterpack.dev/es/docs/config#key) o elimina la directiva. A partir del motor 0.2.3, una directiva que solo reduce la protección se ignora en Free; el motor 0.2.2 también la rechazaba. |
| `DIAG_INPUT_TOO_LARGE` | Una sola entrada excedió el límite de tamaño. |
| `DIAG_BATCH_TOO_LARGE` | Un lote que supera 500 MB en total (413, no reintentable); el build falla de forma segura. |
| `DIAG_INPUT_NESTING_EXCEEDS_ENVIRONMENT` | Error. La entrada anida más profundo de lo que el parser puede manejar con seguridad, estimado antes de analizar contra un límite de 160 niveles. No se escribe salida. Reduce el anidamiento del origen. |
| `DIAG_OUTPUT_NESTING_EXCEEDS_ENVIRONMENT` | Error. La salida ofuscada anidaría más de 400 niveles, el límite que los navegadores y los Workers pueden analizar con seguridad. No se escribe salida. Baja [`complexity`](https://www.afterpack.dev/es/docs/config#complexity) para esa entrada. |
| `DIAG_ENGINE_BUG_NO_PROGRESS` | Critical. El motor no hizo ningún progreso. Esto es un error del motor. |
| `DIAG_ENGINE_BUG_NO_APPLICABLE_TRANSFORM` | Critical. Una parte de un archivo quedó por debajo del objetivo de complejidad sin ninguna transformación desactivada ni directiva de región que lo explique. Esto es un error del motor. |
| `DIAG_ENGINE_BUG_PROCESS_THREAD_PANIC` | Critical. Un hilo worker entró en panic. Esto es un error del motor. |

### Plugin de build / CLI

| Código | Significado |
|---|---|
| `DIAG_DIRECTIVE_UNKNOWN` | Una directiva `@afterpack` nombró una clave no reconocida. Verifícala contra [qué claves](https://www.afterpack.dev/es/docs/directives#what-you-can-set) puede sobrescribir una región. |
| `DIAG_DIRECTIVE_UNSUPPORTED_FORM` | La forma del marcador no se puede colocar (comentario de línea `// @afterpack …`, o el rango `@afterpack:begin/:end`). Usa marcadores de bloque `/* @afterpack … */`. |
| `DIAG_DIRECTIVE_NOT_IMPLEMENTED` | Una clave exclusiva del programa escrita en una directiva (por ejemplo [`reflection.allow`](https://www.afterpack.dev/es/docs/config#reflection-allow)), o una directiva redundante como `skip=false`. Consulta [Qué claves](https://www.afterpack.dev/es/docs/directives#what-you-can-set) para ver qué puede sobrescribir realmente una región. |
| `DIAG_DIRECTIVE_SOURCE_UNRESOLVED` | Info. Una directiva se encuentra en un módulo cuya posición no se pudo mapear en la salida del build, así que no se aplicó. Mueve el código marcado a un módulo importado. |
| `DIAG_DIRECTIVE_DANGLING_END` | Un [`/* @afterpack end */`](https://www.afterpack.dev/es/docs/directives#what-you-can-set) sin ningún bloque abierto arriba. |
| `DIAG_DIRECTIVE_REGION_TO_FILE` | [`identifiers.globals.rename`](https://www.afterpack.dev/es/docs/config#identifiers-globals-rename) no se puede delimitar a una región, así que una directiva que la nombra se ignora y se reporta. |
| `DIAG_DIRECTIVE_COVERAGE_UNVERIFIED` | Un chunk empaquetado que llevaba directivas [no tenía un source map decodificable](https://www.afterpack.dev/es/docs/directives), así que las regiones marcadas no se pudieron ubicar en sus bytes. |
| `DIAG_DIRECTIVE_TARGET_ELIMINATED` | Las directivas se ubicaron en el mapa de un chunk pero no coincidieron con ningún rango. El código marcado fue eliminado por tree-shaking, o las coordenadas no coincidían. |
| `DIAG_ALREADY_OBFUSCATED` | Los archivos recopilados ya llevan la propia salida ofuscada de AfterPack de una ejecución anterior, comparada contra el [recibo de protección](https://www.afterpack.dev/es/docs/cli#afterpack-verify-dir) por hash de contenido. La salida de AfterPack no es idempotente — reconstruye desde el código fuente primero. |
| `DIAG_AFTERPACK_DIR_IN_OUTPUT` | Error, y no se reescribe nada. Hay una carpeta `.afterpack/` dentro de la salida del build, donde sus copias de seguridad, recibos y Protection Maps se publicarían. Bórrala y vuelve a compilar. Consulta [dónde está `.afterpack/`](https://www.afterpack.dev/es/docs/cli#files). |
| `DIAG_RECEIPT_UNWRITABLE` | Error, y no se reescribe nada. El [recibo de protección](https://www.afterpack.dev/es/docs/cli#files) no se puede escribir en `.afterpack/receipts/`. Haz que esa carpeta tenga permisos de escritura y vuelve a compilar. |

### API en la nube

| Código | Significado |
|---|---|
| `DIAG_INVALID_KEY` | [`key`](https://www.afterpack.dev/es/docs/config#key) faltante, malformada, o desconocida (401). Verifica [`AFTERPACK_key`](https://www.afterpack.dev/es/docs/config#key), o emite una clave nueva desde el [panel](https://www.afterpack.dev/es/docs/dashboard/api-keys). |
| `DIAG_KEY_REVOKED` | La clave de API fue revocada (401). |
| `DIAG_KEY_EXPIRED` | La clave de API expiró (401). |
| `DIAG_KEY_OUT_OF_SCOPE` | La IP de la solicitud está fuera del rango permitido para la clave (403). |
| `DIAG_MISSING_IP` | La solicitud no llevaba IP del cliente (400). |
| `DIAG_INVALID_MANIFEST` | Cuerpo multipart malformado, o falta la parte del manifiesto `batch`. |
| `DIAG_FILE_TOO_LARGE` | Un solo archivo superó el límite de bytes por archivo (413). Divídelo, o exclúyelo con [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude). |
| `DIAG_ENTITLEMENT_LAPSED` | Pago de la suscripción vencido (402); actualiza la facturación para seguir construyendo. |
| `DIAG_QUOTA_EXHAUSTED` | El total de bytes del build excede la [asignación restante](https://www.afterpack.dev/es/docs/tiers), o se alcanzó el límite de gasto por exceso. Se verifica una vez por build, antes de que se despache cualquier archivo, así que nada ya protegido se degrada. Recarga, mejora de plan, o sube el límite; el error lleva el enlace. |
| `DIAG_RATE_LIMITED` | Límite de tasa excedido (429); respeta `Retry-After`. |
| `DIAG_RATE_CHECK_UNAVAILABLE` | La propia verificación del límite de tasa falló, así que la solicitud falla de forma segura (503); reintenta. |
| `DIAG_BUILD_DEADLINE` | El presupuesto de tiempo real transcurrió antes de que todos los archivos comenzaran; se indican los archivos sin terminar. |
| `DIAG_ENGINE_FAILURE` | El motor en la nube falló en un archivo. |

### Reflexión en tiempo de ejecución

AfterPack detecta estos patrones de [reflexión en tiempo de ejecución](https://www.afterpack.dev/es/docs/config#reflection-allow): `functionToString`, `nameIntrospection`, `argumentsCallee`, `prototypeChain`, `decoratorMetadata` y `constructorIntrospection`. Cada detección lleva un código: la forma reconocida nombra el patrón, la forma no reconocida es un único `DIAG_REFLECTION_NOT_ACKNOWLEDGED` cuyo mensaje lo nombra.

| Código | Significado |
|---|---|
| `DIAG_REFLECTION_nameIntrospection_ACKNOWLEDGED` | Info. El patrón se detectó y se preservó porque lo reconociste. Un código por patrón; el nombre en medio es cualquiera de los patrones de arriba. |
| `DIAG_REFLECTION_NOT_ACKNOWLEDGED` | Error, salida `5`. Se detectó un patrón de reflexión y **no** se reconoció, así que el build se detiene en vez de entregar código cuya lectura en tiempo de ejecución se rompería; el mensaje nombra el patrón. Reconócelo con [`reflection.allow`](https://www.afterpack.dev/es/docs/config#reflection-allow), que también acepta `angular` y `nestjs`, o saca el archivo con [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude). |

> **Los artefactos sueltos los detecta la auditoría**
>
> Entregar un [`.map`](https://www.afterpack.dev/es/docs/config#sourceMap-enabled) suelto o un archivo hermano sin ofuscar en tu árbol de despliegue lo detecta [`npx afterpack@latest audit`](https://www.afterpack.dev/es/docs/audit), no el build.
>
> Si falta un código o está mal, abre un issue: [github.com/afterpack-dev/afterpack/issues](https://github.com/afterpack-dev/afterpack/issues).

Ejecuta con [`--diagnostics.level=all`](https://www.afterpack.dev/es/docs/config#diagnostics-level) para obtener el flujo completo de diagnósticos en cualquier build, en vez del resumen predeterminado. En un build con plugin, el mismo interruptor es la opción [`diagnostics.level`](https://www.afterpack.dev/es/docs/config#diagnostics-level) o [`AFTERPACK_diagnostics_level`](https://www.afterpack.dev/es/docs/config#diagnostics-level).

## Siguiente

- [Referencia del CLI](https://www.afterpack.dev/es/docs/cli): todos los flags a los que hacen referencia los códigos de arriba.
- [Configuración](https://www.afterpack.dev/es/docs/config): las claves de configuración a las que hacen referencia estos códigos.
- [Contrato semántico](https://www.afterpack.dev/es/docs/semantic-contract): lo que la salida mantiene igual y las pocas diferencias deliberadas.
- [Directivas](https://www.afterpack.dev/es/docs/directives): la gramática completa de `@afterpack` detrás de los códigos de directiva de arriba.
- [Buenas prácticas](https://www.afterpack.dev/es/docs/best-practices): los patrones que evitan estos diagnósticos desde el principio.
- [Planes](https://www.afterpack.dev/es/docs/tiers): qué es Free y qué necesita una [`key`](https://www.afterpack.dev/es/docs/config#key).
