---
title: "verbatra check"
description: "Informa de qué claves faltan o están obsoletas por locale sin escribir archivos ni llamar a un proveedor, y hace fallar la CI mientras un locale no esté al día."
type: "reference"
---
# verbatra check

Informa de qué claves faltan o están obsoletas por locale sin escribir archivos ni llamar a un proveedor, y hace fallar la CI mientras un locale no esté al día.

Informa, por cada locale de destino, de cuántas claves faltan, están obsoletas o al día, y termina con un código en el que un paso de CI puede ramificar. `check` lee y compara como [`verbatra translate`](https://verbatra.kreitz-webdev.de/es/docs/cli/translate.md) antes de llamar al proveedor y se detiene ahí: sin llamada al proveedor, sin escribir archivos, sin clave de API.

## Sinopsis [#sinopsis]

```bash
verbatra check [flags]
```

## Ejemplos [#ejemplos]

```bash
# hacer fallar el build cuando las traducciones se desfasaron
verbatra check

# estado legible por máquina para dos locales
verbatra check --locales de,fr --json

# listar además los textos de origen traducidos de más de una forma
verbatra check --consistency

# fallar ante placeholders, markup e ICU rotos, y también ante avisos
verbatra check --qa --strict

# fallar mientras haya traducciones automáticas esperando aprobación
verbatra check --require-reviewed

# fallar ante correos, claves de API o números de tarjeta en el origen
verbatra check --sensitive

# comprobar solo el archivo que un editor o un agente acaba de cambiar
verbatra check --file locales/de.json --json
```

## Flags [#flags]

| Flag | Argumento | Por defecto | Efecto |
| --- | --- | --- | --- |
| `--locales` | `<list>` | todos los destinos configurados | comprueba solo este subconjunto separado por comas; un locale no configurado falla con `UNKNOWN_LOCALE` y una lista vacía con `INVALID_LOCALES`, ambos con salida `2` |
| `--consistency` | ninguno | desactivado | lista además los textos de origen traducidos de más de una forma; solo informa, mira el [informe de consistencia](#informe-de-consistencia) |
| `--qa` | ninguno | desactivado | ejecuta además el [control de calidad](#control-de-calidad) sobre cada traducción confirmada; sale con `1` ante un error |
| `--file` | `<path>` | desactivado | comprueba solo este archivo de locale, mira [Un solo archivo](#un-solo-archivo); no junto a `--locales`, `--consistency`, `--require-reviewed` ni `--sensitive` |
| `--severity` | `error` o `warning` | `warning` | con `--qa` o `--file`, la gravedad mínima que se informa |
| `--strict` | ninguno | desactivado | con `--qa` o `--file`, sale también con `1` ante un aviso o un [plural incompleto](#categorías-de-plural); no junto a `--severity error` |
| `--require-reviewed` | ninguno | desactivado | sale además con `1` mientras una traducción escrita por máquina [no esté aprobada](#exigir-traducciones-revisadas) |
| `--sensitive` | ninguno | desactivado | revisa además el archivo de origen y el glosario en busca de [contenido sensible](#contenido-sensible); sale con `1` ante cualquier hallazgo |

También acepta los [flags globales](https://verbatra.kreitz-webdev.de/es/docs/cli.md#flags-globales) `--cwd`, `--config` y `--json`.

Una clave falta cuando el origen la tiene y el destino no, y está obsoleta cuando su texto de origen cambió desde la última traducción. Un locale está sincronizado cuando no tiene ninguna de las dos. Para ver las listas de claves detrás de los recuentos, usa [`verbatra diff`](https://verbatra.kreitz-webdev.de/es/docs/cli/diff.md).

## Comportamiento [#comportamiento]

### Informe de consistencia [#informe-de-consistencia]

<AvailableFrom version="0.11.0" />

`--consistency` lista, por locale de destino, cada texto de origen que dos o más claves traducen de forma distinta: el origen, cada traducción y las claves que la llevan. Nunca cambia el código de salida, un valor ni la cola de revisión. Las reglas de comparación:

- Los valores se comparan tras la normalización Unicode NFC, con `\r\n` convertido en `\n` y sin espacios al principio ni al final. Los espacios internos y las mayúsculas cuentan.
- Solo se comparan claves al día, y una traducción igual a su origen queda para `EQUALS_SOURCE`.
- Nunca se agrupan claves cuya descripción, significado, marca de plural o `msgctxt` de gettext difieran.
- Las formas de plural se comparan por forma: las formas `one` y `other` de una clave nunca se agrupan entre sí.

Falsos positivos conocidos: variantes de contexto de i18next (`invite_male`, `invite_female`), entradas de gettext marcadas con `#, fuzzy`, claves con aspecto de plural en un formato sin plurales (`yaml`, `ngx-translate-json`, `xliff`, `properties`, `ini`, `resx`) y las formas de plural de un formato `custom:`. Dales una descripción o un significado distintos, o ignora el hallazgo. Con `--json`, cada locale lleva `inconsistencies: { source, context?, description?, meaning?, isPlural, pluralForm?, translations: [{ value, keys }] }[]`.

### Claves protegidas [#claves-protegidas]

<AvailableFrom version="0.12.0" />

Una clave obsoleta que una persona escribió, importó o cambió fuera de verbatra, o una clave que coincide con `pinnedKeys`, es una que `translate` deja para una persona (mira [Proteger las traducciones humanas](https://verbatra.kreitz-webdev.de/es/docs/protecting-human-translations.md)). `check` la sigue contando y muestra la parte protegida, por ejemplo `2 stale (1 protected)`. `--json` la da como `protected` por locale; si `verbatra.provenance.json` no se puede leer, solo cuentan las claves fijadas.

### Categorías de plural [#categorías-de-plural]

<AvailableFrom version="0.12.0" />

Cada `check` lista los plurales a los que les falta una categoría de plural CLDR que usa su idioma de destino, como un `<plurals>` de Android en polaco con solo `one` y `other`:

```text output
plural categories (warning: exit 1 only under --qa --strict)
  pl: 2 plurals missing CLDR categories
    cart {count} plural: missing few, many
    files: missing few, many
```

Las categorías salen de las reglas CLDR integradas en Node.js (mira [soporte de idiomas](https://verbatra.kreitz-webdev.de/es/docs/language-support.md#plurales)). Formatos comprobados:

| Formato | Formas de plural leídas |
| --- | --- |
| `i18next-json` | los sufijos de clave `_one`, `_few`, ... y los plurales `_ordinal_` frente a las reglas ordinales |
| `android-xml` | las entradas `<item quantity>` de cada `<plurals>` |
| `apple-strings` | las reglas de plural del `.stringsdict` junto al archivo `.strings` |
| `apple-xcstrings` | las categorías `variations.plural` de cada locale |
| `next-intl-json`, `arb` | cada `plural` y `selectordinal` de ICU, también los anidados |

`other` siempre es obligatoria. Una rama exacta como `=1` nunca sustituye a una categoría, las ramas de `select` nunca se comprueban y solo se comprueba un plural del que el destino tiene al menos una forma. Es un aviso: un `check` simple conserva su código de salida y `--qa --strict` falla por él. [`verbatra doctor`](https://verbatra.kreitz-webdev.de/es/docs/cli/doctor.md) informa de los mismos plurales. Con `--json`, cada locale lleva `incompletePlurals`, ordenado por clave:

```ts
interface IncompletePlural {
  code: "PLURAL_CATEGORIES_INCOMPLETE";
  key: string;              // clave base, o la clave del mensaje ICU
  argument?: string;        // el argumento del plural ICU, como count
  ruleType: "cardinal" | "ordinal";
  missing: ("zero" | "one" | "two" | "few" | "many" | "other")[]; // en orden CLDR
}
```

### Control de calidad [#control-de-calidad]

<AvailableFrom version="0.12.0" />

`--qa` aplica las comprobaciones que una ejecución de traducción hace sobre la salida del proveedor a los valores que ya están en tus archivos de locale, obsoletos o no, incluidas las formas de plural extra que necesita el idioma de destino. Los hallazgos tienen dos gravedades:

- **error**: el valor no pasa la [puerta de integridad](https://verbatra.kreitz-webdev.de/es/docs/translation-safety.md#la-puerta-de-integridad), con `placeholder`, `markup`, `icu`, `degenerate` o `empty`. Los detalles listan los tokens perdidos como `-{{name}}` y los añadidos como `+{{nom}}`.
- **warning**: el valor lleva un [motivo de revisión](https://verbatra.kreitz-webdev.de/es/docs/translation-safety.md#señales-de-revisión) calculado a partir del valor, su origen y tu configuración (glosario, `maxLength`), así que ninguno que dependa del proveedor o de la caché; con `FOREIGN_PLACEHOLDER_CHANGED`, los `details` del hallazgo nombran cada token perdido o cambiado, como `-{name}`. Un valor con error no recibe avisos.

```text output
qa: 1 error, 1 warning
  de: 1 error, 1 warning in 42 values checked
    greeting: error placeholder (-{{name}}, +{{nme}})
    title: warning EQUALS_SOURCE
```

Las claves huérfanas y las que faltan se omiten, y las claves de origen que no son ICU válido aparecen una vez en `invalidSourceKeys`. Los valores protegidos, fijados y rechazados se comprueban como cualquier otro. Con `--json`, `result.qa` guarda los totales y cada locale su propio `qa`:

```ts
interface CheckQaSummary { errors: number; warnings: number; invalidSourceKeys: string[] }
interface LocaleQaReport { checked: number; errors: number; warnings: number; findings: QaFinding[] }
type QaFinding =
  | { key: string; severity: "error"; reason: "placeholder" | "markup" | "icu" | "degenerate" | "empty"; details?: string[] }
  | { key: string; severity: "warning"; reason: string; details?: string[] }; // uno de los motivos de revisión de arriba
```

### Exigir traducciones revisadas [#exigir-traducciones-revisadas]

<AvailableFrom version="0.12.0" />

`--require-reviewed` falla con `1` mientras un valor cuyo [origen](https://verbatra.kreitz-webdev.de/es/docs/the-lock-file.md#procedencia-quién-escribió-cada-valor) sea `machine`, `memory`, `fuzzy` o `agent` no esté aprobado en el `verbatra.provenance.json` confirmado, donde [Studio](https://verbatra.kreitz-webdev.de/es/docs/review-in-studio.md) y las [herramientas MCP](https://verbatra.kreitz-webdev.de/es/docs/cli/mcp.md) guardan sus decisiones. Una aprobación anterior al cambio del texto de origen o del valor no cuenta.

```text output
review: failed [REVIEW_REQUIRED] 2 machine-written translations not approved
  de: 2 unreviewed: checkout.title, checkout.total
```

Con `--json`, `result.review` es `{ reviewed, unreviewed, code? }`, donde `code` es `REVIEW_REQUIRED`, o `REVIEW_STATE_UNREADABLE` cuando el archivo de procedencia está dañado o viene de un verbatra más nuevo (entonces la puerta falla). Cada locale lleva `review.unreviewed`, las claves en el orden del origen.

### Contenido sensible [#contenido-sensible]

<AvailableFrom version="0.12.0" />

`--sensitive` ejecuta la revisión de la [protección de contenido sensible](https://verbatra.kreitz-webdev.de/es/docs/data-handling.md#protección-de-contenido-sensible) sobre cada clave de origen (nombre de clave, valor, descripción y significado) y el glosario de cada locale comprobado, con los detectores, patrones y la lista `allow` de `sensitiveData` (sin bloque, los detectores por defecto), con cualquier `mode` y proveedor, `none` incluido: los valores siguen saliendo del equipo en entregas por exportación, XLIFF y TMX. Informa de claves y detectores, nunca del texto encontrado fuera de un nombre de clave, y sale con `1` ante cualquier hallazgo.

El detector `email` omite los [dominios de ejemplo reservados](https://verbatra.kreitz-webdev.de/es/docs/data-handling.md#protección-de-contenido-sensible), así que prueba con una dirección de aspecto real.

```text output
sensitive: 1 key and 0 glossary terms hold content that looks sensitive
  support.contact: email in value
```

Con `--json`, `result.sensitive` es `{ findings, glossaryTerms }`, y cada hallazgo `{ key, fields, detectors }`; `detectors` puede incluir `pattern-timeout-<n>`.

### Un solo archivo [#un-solo-archivo]

<AvailableFrom version="0.12.0" />

`--file <path>` comprueba un único archivo de locale, pensado para hooks de editor y de agente tras una edición. Lee ese archivo, `verbatra.limits.json` <AvailableFrom version="0.13.0" /> (si no se puede usar, se ignora con un aviso en stderr, como con `--qa`; [`doctor`](https://verbatra.kreitz-webdev.de/es/docs/cli/doctor.md) nombra el problema) y, para un locale de destino, el archivo de origen, nada más. La ruta se resuelve respecto a `--cwd` y se asocia a su locale mediante `files.pattern`.

- Un archivo que no se puede analizar da un error `syntax` con el código del adaptador (`INVALID_JSON`, `INVALID_YAML`, ...) y la línea y la columna cuando el analizador informa de una posición.
- Un archivo de destino se comprueba como con [`--qa`](#control-de-calidad), categorías de plural incluidas; un archivo de origen, solo la sintaxis. Un catálogo `apple-xcstrings` se comprueba para cada locale de destino.
- Una ruta que no es el archivo de ningún locale configurado falla con `NOT_A_LOCALE_FILE` y sale con `2`.

Con `--json`, `result` reutiliza el informe de `--qa`, así que un hook analiza una sola forma:

```ts
interface CheckFileSummary {
  file: string;                          // relativo a la raíz del proyecto
  role: "source" | "target" | "catalogue";
  locales: {
    locale: string;
    incompletePlurals: IncompletePlural[];
    qa: { checked: number; errors: number; warnings: number; findings: (QaFinding | QaSyntaxFinding)[] };
  }[];
  qa: CheckQaSummary;
}
interface QaSyntaxFinding {
  severity: "error"; reason: "syntax"; code: string; message: string;
  line?: number; column?: number;       // si el analizador informa de una posición, contando desde 1
}
```

Las claves que faltan y las obsoletas no forman parte de la comprobación de un archivo.

### Salida JSON [#salida-json]

Esquema: [`check-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/check-envelope.json) valida el envoltorio completo; [Esquemas](https://verbatra.kreitz-webdev.de/es/docs/cli/output.md#esquemas) enumera los demás.

`--json` imprime un [envoltorio](https://verbatra.kreitz-webdev.de/es/docs/cli/output.md#salida-json) cuyo `result` es el documento de estado. Sin `--qa`, `--require-reviewed` ni `--sensitive`, `inSync` es verdadero exactamente cuando el comando sale con `0`:

```ts
interface CheckSummary {
  inSync: boolean;
  locales: LocaleCheckSummary[];
  qa?: CheckQaSummary;          // solo con --qa
  review?: CheckReviewSummary;  // solo con --require-reviewed
  sensitive?: CheckSensitiveSummary; // solo con --sensitive
}

interface LocaleCheckSummary {
  locale: string;
  missing: number;              // en el origen, ausente del destino
  stale: number;                // el origen cambió desde la última traducción
  upToDate: number;
  inSync: boolean;              // missing === 0 && stale === 0
  emptySource?: number;         // valor de origen vacío: nunca falta ni está desactualizado
  provenance?: ProvenanceSummary; // recuentos por origen y estado de revisión
  protected?: number;
  incompletePlurals?: IncompletePlural[];
  inconsistencies?: InconsistencyGroup[]; // solo con --consistency
  qa?: LocaleQaReport;          // solo con --qa
  review?: LocaleReviewReport;  // solo con --require-reviewed
}
```

Una clave de origen cuyo valor está vacío o solo tiene espacios, como una que `extract` añadió sin valor por defecto, aún no tiene nada que traducir: se cuenta en `emptySource` en lugar de `missing` o `stale`, nunca deja un locale fuera de sincronía, y la salida de terminal indica el número.

### Información en el terminal [#información-en-el-terminal]

<AvailableFrom version="0.12.0" />

`check` muestra `verbatra: checking the locales... done (0.1s)` en stderr, o `verbatra: checking locales/de.json...` con `--file`. `--quiet` la omite. Mira [Salida en el terminal](https://verbatra.kreitz-webdev.de/es/docs/cli/output.md#salida-en-el-terminal).

## Códigos de salida [#códigos-de-salida]

| Código | Significado |
| --- | --- |
| `0` | sincronizado, y ningún hallazgo que los flags usados conviertan en fallo |
| `1` | un locale tiene una clave que falta u obsoleta, `--qa` o `--file` encontró un error (o, con `--strict`, un aviso o un plural incompleto), `--require-reviewed` encontró una traducción sin aprobar, o `--sensitive` encontró contenido sensible |
| `2` | no pudo ejecutarse: un error de toda la ejecución como `SOURCE_UNREADABLE` o `NOT_A_LOCALE_FILE`, o un error de uso como `INVALID_QA_OPTION`, `INVALID_SEVERITY` o `INVALID_OPTION` para un `--file` vacío o combinado con `--locales`, `--consistency`, `--require-reviewed` o `--sensitive` |

La salida `1` significa que el resultado no está limpio, no que la ejecución fallara; el informe se imprime igual. En un proyecto cuyo archivo de origen aún no existe, [`verbatra doctor`](https://verbatra.kreitz-webdev.de/es/docs/cli/doctor.md) sigue informando. El contrato está en [Códigos de salida](https://verbatra.kreitz-webdev.de/es/docs/cli/output.md#códigos-de-salida).

## Relacionado [#relacionado]

- [`verbatra diff`](https://verbatra.kreitz-webdev.de/es/docs/cli/diff.md) lista las claves exactas detrás de estos recuentos.
- [CI y códigos de salida](https://verbatra.kreitz-webdev.de/es/docs/ci-and-exit-codes.md) muestra `check` como puerta contra desfases.
- [El archivo de bloqueo](https://verbatra.kreitz-webdev.de/es/docs/the-lock-file.md) explica cómo se detecta que algo está obsoleto.
