---
title: "verbatra doctor"
description: "Vérifie qu'un projet est bien configuré et obtiens tous les problèmes dans un seul rapport, sans appeler de fournisseur ni lire de clé d'API."
type: "reference"
---
# verbatra doctor

Vérifie qu'un projet est bien configuré et obtiens tous les problèmes dans un seul rapport, sans appeler de fournisseur ni lire de clé d'API.

<AvailableFrom version="0.9.0" />

Vérifie qu'un projet est bien configuré et obtiens tous les problèmes dans un seul rapport. `doctor` ne construit aucun fournisseur, n'écrit aucun fichier et ne lit la valeur d'une clé d'API que pour `--live`, qui l'envoie dans une requête de la liste des langues du fournisseur (LibreTranslate n'en reçoit aucune). Lance-le après [`verbatra init`](https://verbatra.kreitz-webdev.de/fr/docs/cli/init.md) ou quand une autre commande échoue.

## Synopsis [#synopsis]

```bash
verbatra doctor [flags]
```

## Exemples [#exemples]

```bash
# report every setup problem at once
verbatra doctor

# validate a project in another directory, with an explicit config
verbatra doctor --cwd apps/web --config verbatra.config.ts

# machine-readable report for a CI preflight step
verbatra doctor --json

# list hardcoded user-facing strings, with no key set
verbatra doctor --literals

# what the provider supports for each target locale
verbatra doctor --locales

# the same, against the provider's current language list
verbatra doctor --live

# a data-flow manifest to attach to a DPA or NDA review
verbatra doctor --data-flow --json
```

## Options [#options]

| Option | Argument | Défaut | Effet |
| --- | --- | --- | --- |
| `--literals` | aucun | désactivé | au lieu de vérifier la configuration, cherche des chaînes visibles par l'utilisateur écrites en dur dans les racines de code du [bloc `extract`](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract) (voir [Littéraux non traduits](#littéraux-non-traduits)) |
| `--locales` | aucun | désactivé | après les vérifications, liste par locale cible le code envoyé, la prise en charge du fournisseur, le glossaire et la formalité (voir [Prise en charge des locales](#prise-en-charge-des-locales)) |
| `--live` | aucun | désactivé | récupère d'abord la liste de langues actuelle du fournisseur, sans consommer de quota de traduction ; implique `--locales` |
| `--data-flow` | aucun | désactivé | au lieu de vérifier la configuration, décrit ce qui est envoyé à quel hôte et ce qui est écrit en local (voir [Flux de données](#flux-de-données)) |

Accepte aussi les [options globales](https://verbatra.kreitz-webdev.de/fr/docs/cli.md#options-globales) `--cwd`, `--config` et `--json`. `--locales` et `--live` ne se combinent pas avec `--literals` (`INVALID_OPTION`, sortie `2`), et `--data-flow` avec aucune des trois.

## Comportement [#comportement]

### Ce qu'il vérifie [#ce-quil-vérifie]

<AvailableFrom version="0.12.0" />

Une exécution de configuration rapporte ces vérifications, dans cet ordre. Plural rules, Plural completeness, Locale codes, Locale state et Length limits sont informatives et n'échouent jamais : chacune affiche `[warn]` quand elle nomme quelque chose et `[ok  ]` sinon.

| Vérification | Échoue quand |
| --- | --- |
| Configuration | aucun fichier de configuration n'est trouvé, ou il ne passe pas la validation |
| Format adapter | le `format` configuré ne se résout en aucun adaptateur de fichiers |
| Provider | le `provider.id` configuré ne se résout en aucune factory de fournisseur |
| API key environment variable | la variable dans laquelle ce fournisseur lit sa clé n'est pas définie |
| Network policy | la [politique réseau](https://verbatra.kreitz-webdev.de/fr/docs/network-policy.md) effective refuse l'hôte du fournisseur ou un proxy qu'il utiliserait |
| Source locale file | le fichier de locale source manque à son chemin résolu, n'est pas un fichier ordinaire ou ne s'analyse pas avec le format configuré |
| Plural rules | jamais ; nomme les versions d'ICU et de CLDR utilisées et avertit quand une locale cible n'a pas de règles de pluriel dans ICU |
| Plural completeness | jamais ; avertit et nomme chaque pluriel cible auquel il manque une catégorie CLDR utilisée par sa langue, et juge un pluriel sans formes dans la cible d'après ce qu'une exécution y écrirait (une forme source vide compte comme absente, et la génération des pluriels seulement là où elle s'exécute vraiment), volontairement plus strict que l'avis de `translate`, propre à i18next (dix au plus ; [`verbatra check`](https://verbatra.kreitz-webdev.de/fr/docs/cli/check.md#catégories-de-pluriel) liste les manques des pluriels qu'une cible contient déjà) ; ignorée pour un format qui ne stocke pas les formes de pluriel par catégorie CLDR |
| Locale codes | jamais ; avertit et nomme chaque code valide mais non canonique, comme `en-us` ou `iw`, avec sa forme canonique (voir [Codes de locale](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#codes-de-locale)) |
| Locale state | jamais ; avertit et nomme chaque locale pour laquelle le fichier de verrou, le cache ou le fichier de provenance gardent un état que la configuration ne liste pas, et si `translate` le [reprend](https://verbatra.kreitz-webdev.de/fr/docs/the-lock-file.md#un-code-de-locale-réécrit) |
| Length limits | jamais ; avertit quand `verbatra.limits.json` est inutilisable (une exécution l'ignore et une limite ne peut être fixée qu'une fois réparé), nomme une limite pour une clé que la source n'a plus ou une que le `maxLength` de la configuration remplace, et le dit quand la source n'a pas pu être lue pour vérifier les clés ; réussit quand le fichier est absent ([limites de longueur](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#maxlength)) <AvailableFrom version="0.13.0" /> |
| Locale support | le fournisseur ne prend pas en charge la locale source ou une locale cible ; avertit quand une locale porte un avertissement (voir [Prise en charge des locales](#prise-en-charge-des-locales)) |

Chaque vérification s'exécute même si une précédente a échoué. La seule exception est la configuration : si elle ne peut pas être chargée, les vérifications qui en dépendent s'affichent en `[skip]` (`"status": "skipped"` en JSON), tout comme Plural completeness pour un format sans formes de pluriel CLDR. Une vérification qui trouve quelque chose méritant attention sans échouer s'affiche en `[warn]` (`"status": "warn"` en JSON) et ne change jamais le code de sortie. Une vérification échouée porte aussi un `fix`, une prochaine étape à l'impératif affichée en ligne `fix:` et transmise comme `"fix"` en JSON, pour qu'un agent agisse sans analyser `detail`.

Une exécution avec deux problèmes :

```text output
verbatra doctor
  [ok  ] Configuration: Loaded /app/verbatra.config.ts.
  [ok  ] Format adapter: Format "i18next-json" resolves to an adapter.
  [ok  ] Provider: Provider "anthropic" resolves to a factory.
  [fail] API key environment variable: The ANTHROPIC_API_KEY environment variable is not set.
         fix: Set ANTHROPIC_API_KEY in the environment, or, with the CLI, in a .env file in the project directory.
  [ok  ] Network policy: any host (config: unset; VERBATRA_NETWORK_POLICY: unset). Provider "anthropic" connects to api.anthropic.com: permitted.
  [fail] Source locale file: The source locale file was not found at /app/locales/en.json.
         fix: Create the source locale file, or fix `files.pattern` and `sourceLocale` in the config so they point at it.
  ...
  [warn] Locale codes: "iw" is canonically "he". Consider the canonical form in your config; file names follow the configured code and are never renamed for you.
  [ok  ] Locale support: Provider "anthropic" is an LLM and accepts any locale (well-tested list of 2026-09-28).
2 problems found (run verbatra doctor again after fixing them)
```

### Clés et fichiers [#clés-et-fichiers]

- La clé d'API est vérifiée **par son nom uniquement** : `doctor` demande si la variable est définie, jamais ce qu'elle contient. La variable de chaque fournisseur est dans [Fournisseurs](https://verbatra.kreitz-webdev.de/fr/docs/providers.md).
- `openai-compatible` se rabat sur une clé factice, il n'échoue donc que si la configuration nomme sa propre variable dans `provider.options.apiKeyEnvVar` et que cette variable n'est pas définie. `libretranslate` ne fait jamais échouer la vérification, car sa clé est facultative.
- Avec [`provider: { id: "none" }`](https://verbatra.kreitz-webdev.de/fr/docs/human-only-workflow.md), les vérifications Provider, API key et Network policy passent, et Locale support est ignorée.
- Un fichier **cible** manquant n'est pas un problème : `translate` le crée. Le fichier **source** est analysé, donc un répertoire, un fichier vide ou un contenu mal formé la fait échouer.
- `doctor` charge d'abord les [fichiers d'environnement](https://verbatra.kreitz-webdev.de/fr/docs/cli.md#fichiers-denvironnement), donc une clé dans un fichier dotenv compte comme définie ; avec `--literals`, il n'en charge aucun.

### Prise en charge des locales [#prise-en-charge-des-locales]

<AvailableFrom version="0.12.0" />

La vérification Locale support demande si le fournisseur peut traduire chaque locale configurée. DeepL et Google Cloud Translation sont évalués d'après une table de langues datée que verbatra embarque ; un fournisseur LLM accepte toute locale. Elle échoue exactement sur la locale que [`verbatra translate`](https://verbatra.kreitz-webdev.de/fr/docs/cli/translate.md) refuserait avec `LOCALE_UNSUPPORTED_BY_PROVIDER`, et affiche sinon `[warn]` quand une locale porte un avertissement ou que `--live` n'a pas pu récupérer la liste. [Prise en charge des langues](https://verbatra.kreitz-webdev.de/fr/docs/language-support.md#vérifier-la-prise-en-charge-avant-une-exécution) explique les verdicts.

`--locales` affiche le verdict par locale après les vérifications :

```text output
  locale support (deepl, language table of 2026-09-28, static)
    en  sent as EN  source, supported
    de  sent as DE  supported  glossary: yes  formality: yes
    sv  sent as SV  supported  glossary: yes  formality: no
      warning [FORMALITY_UNSUPPORTED_BY_PROVIDER] Provider "deepl" has no formality control for "sv", so the configured formal tone is not applied and the provider's default register is used.
    chr  sent as CHR  unsupported  glossary: no  formality: no
```

Chaque ligne nomme la locale, le code que reçoit le fournisseur (après [`localeMap`](https://verbatra.kreitz-webdev.de/fr/docs/providers.md#codes-de-locale-envoyés-au-fournisseur), marqué `(localeMap)`), le verdict, et si un glossaire et un ton `formal` ou `informal` s'appliquent. Un avertissement est indicatif.

`--live` évalue plutôt d'après la liste actuelle du fournisseur (DeepL `/v3/languages`, Cloud Translation `languages`, LibreTranslate `/languages`). Pour LibreTranslate, qui n'embarque aucune table, c'est le seul moyen d'obtenir un autre verdict que `unverified` : Locale support affiche donc `[warn]` tant que `--live` n'a pas tourné. La requête n'est envoyée que si la variable de clé est définie (LibreTranslate n'en a pas besoin) et que la [politique réseau](https://verbatra.kreitz-webdev.de/fr/docs/network-policy.md) autorise l'hôte ; sinon, ou en cas d'échec, la table embarquée sert et une ligne `live language list` dit pourquoi.

### Littéraux non traduits [#littéraux-non-traduits]

<AvailableFrom version="0.11.0" />

`--literals` trouve les chaînes visibles par l'utilisateur qui ne sont jamais arrivées dans un catalogue. Il parcourt les racines de code de ton [bloc `extract`](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract), lit ton code sans jamais l'écrire, ne construit aucun fournisseur, ne lit aucune clé et ne charge aucun `.env`. Seules deux vérifications s'exécutent : Configuration et Untranslated literals. Chaque résultat nomme fichier, ligne et colonne, avec les espaces regroupés, les références de caractères JSX décodées et 80 caractères au plus :

```text output
  [fail] Untranslated literals: Scanned 42 source files: 2 untranslated literals found (1 suppressed).
    src/components/Header.tsx:12:9  "Welcome back"
    src/pages/settings.tsx:40:22  "Save changes"
    suppressed (directive) src/pages/legal.tsx:8:5  "Acme Inc."
```

Sont signalés : le texte JSX dans les fichiers `.tsx`, `.jsx` et `.js`, les attributs JSX visibles par l'utilisateur (`alt`, `title`, `placeholder`, `label`, `aria-label` et les autres `aria-*` porteurs de texte), et toute autre chaîne de deux mots ou plus.

Ne sont jamais signalés :

- une chaîne passée à `t(...)`, `$t(...)`, `i18n.t(...)` ou à un `t` renommé issu de `useTranslation`, ou rendue dans `<Trans>` ou `<Translation>` ;
- les clés d'objet, spécificateurs d'import, noms de classe, valeurs CSS, identifiants de test, `data-*` et attributs d'identifiant ou de mot-clé (`aria-describedby`, `aria-labelledby`, `aria-controls`, `rel`, `sandbox`, `allow`, `autoComplete`, `referrerPolicy`, `crossOrigin`), les URL et les chaînes sans lettres ;
- les littéraux en position de type (la valeur avant `as` ou `satisfies` reste vérifiée), les messages de log, les messages d'erreur (`new ValidationError(...)`, `throw Error(...)`), les opérandes de comparaison et les template literals contenant une expression ;
- les arguments directs de `describe` (zod), `query`, `execute`, `prepare`, `format`, `parse`, `z.enum`, `setItem`, `getItem` et `removeItem`, et le premier argument de `on`, `off`, `once`, `emit`, `addEventListener` et d'un `get` ou `set` sur un objet ; le texte plus imbriqué et les messages passés à des fonctions comme `setError` restent signalés ;
- tout ce qui se trouve dans les fichiers de test, de story, de déclaration ou de configuration.

Pour retenir un littéral, place `// verbatra-ignore-next-line` au-dessus (en JSX, `{/* verbatra-ignore-next-line */}`) ou `// verbatra-ignore-line` en fin de ligne. Une directive de ligne suivante vise la prochaine ligne contenant du code et, sur une balise JSX ouvrante, tous ses attributs. Une chaîne acceptable partout va dans `extract.literals.ignore`, références décodées (`Tom & Jerry`). Les littéraux supprimés restent listés avec leur raison.

La vérification échoue sur un résultat et sur un fichier qu'elle n'a pas pu ouvrir, lire jusqu'au bout, ou jugé trop gros (l'analyse continue). Un projet sans bloc `extract` la fait échouer.

### Flux de données [#flux-de-données]

<AvailableFrom version="0.12.0" />

`--data-flow` décrit où vont les données de ce projet au lieu de vérifier la configuration, comme preuve pour une revue DPA ou NDA ; [Traitement des données](https://verbatra.kreitz-webdev.de/fr/docs/data-handling.md) explique chaque catégorie. Il ne lit aucune clé d'API et ne fait aucune requête réseau. Seules deux vérifications s'exécutent : Configuration et Data flow. Data flow n'échoue jamais : il affiche `[warn]` quand la [politique réseau](https://verbatra.kreitz-webdev.de/fr/docs/network-policy.md) refuse un hôte ou contient une valeur invalide, ou quand le fichier source ne peut pas être lu pour les décomptes.

```text output
  [ok  ] Data flow: Provider "deepl" sends source-text, placeholder-markers, language-codes to api.deepl.com (permitted), api-free.deepl.com (permitted).
  data flow (manifest version 1)
    provider     deepl (machine-translation)
    network      any host (no policy set)
    destination  api.deepl.com  default  paid-key  before-construction  permitted
    destination  api-free.deepl.com  default  free-key  before-construction  permitted
    sent         source-text, placeholder-markers, language-codes
    api key      required
    placeholders masked
    sensitive    off
    counts       3 source keys, 0 with a description or meaning, 1 with placeholders it cannot mask (withheld)
    locale       de  sent as DE  glossary terms: 0
    local        lock  verbatra.lock.json  (no source text, translations or personal data)
    local        provenance  verbatra.provenance.json  (reviewer names)
    local        cache  verbatra.cache.json  (source text, translations, gitignored by init)
    local        local-state  .verbatra-local  (source text, host name and process ID of a run holding a write lock, gitignored by init)
    request      language-list  verbatra doctor --live  sends the API key
    request      dns-lookup  each connection to a destination host
    agent        mcp  verbatra mcp  redactable
    agent        studio-agent-tools  verbatra studio --expose-agent-tools
```

Le manifeste nomme le fournisseur ; chaque hôte de destination, d'où il vient (intégré, `provider.options.baseUrl` ou une variable `*_BASE_URL`) et le verdict de la politique (`permitted`, `deferred`, `refused` ou `invalid-policy`) ; les types de données envoyées, avec le nombre de clés source, de clés portant une description ou un sens, et de clés dont le fournisseur ne peut pas masquer les placeholders (une estimation sur les clés source : une exécution n'envoie que les clés manquantes ou modifiées et peut en retenir davantage avec `sensitiveData: redact`) ; le code et le nombre de termes du glossaire par locale cible ; les fichiers locaux avec leurs chemins relatifs au projet, et s'ils contiennent du texte source, des traductions ou des données personnelles ; et les autres requêtes et surfaces d'agents. DeepL figure avec ses deux hôtes, car la clé qui en choisit un n'est jamais lue. Un proxy actif figure avec sa variable et son hôte, jamais ses identifiants, et les champs ne nomment que ce que cette config peut envoyer. Avec `provider: { id: "none" }`, il indique que rien n'est envoyé. Il nomme des hôtes, des catégories de données et des conditions, jamais la valeur d'une clé ni le contenu d'un fichier.

Avec `--json`, le manifeste est sous `result.dataFlow`. Son champ `version` ne change que lorsqu'un champ est renommé ou supprimé ; de nouveaux champs peuvent apparaître sans la changer, alors ignore ceux que tu ne connais pas. [`dataFlowManifestSchema`](https://verbatra.kreitz-webdev.de/fr/docs/sdk/inspect.md#dataflowmanifestschema) du SDK le valide.

### Sortie JSON [#sortie-json]

Schéma : [`doctor-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/doctor-envelope.json) valide l'enveloppe entière ; [Schémas](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#schémas) liste les autres.

Avec `--json`, l'[enveloppe](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#sortie-json) porte le rapport sous `result`. `ok` est vrai exactement quand la commande sort avec `0` :

```ts
interface DoctorResult {
  ok: boolean;                 // true exactly when the command exits 0
  checks: DoctorCheck[];       // one per check, always in the same order
  literals?: LiteralScan;      // only with --literals: findings, suppressed, diagnostics
  dataFlow?: DataFlowManifest; // only with --data-flow: what goes where, version 1
  locales?: LocaleCapabilityReport; // per-locale provider support, with or without --locales
}

interface DoctorCheck {
  id:
    | "config"
    | "format-adapter"
    | "provider"
    | "api-key"
    | "network-policy"
    | "source-file"
    | "plural-rules"
    | "plural-completeness"
    | "locale-codes"
    | "locale-state"
    | "limits" // 0.13.0
    | "locales"
    | "untranslated-literals"
    | "data-flow";
  title: string;               // stable, human-readable name
  status: "pass" | "warn" | "fail" | "skipped";  // only "fail" makes ok false
  detail: string;              // why it reached that verdict; never an API key value
  fix?: string;                // the next step, only on a failed check
}

interface LocaleCapabilityReport {
  provider: string;
  coverage: "listed" | "open";       // "open" for an LLM provider
  tableVersion: string;              // the table's date (YYYY-MM-DD)
  tableOrigin: "static" | "live";    // "live" only when --live fetched the list
  live?: { status: "refreshed" | "skipped" | "failed"; detail: string }; // only with --live
  source: {
    locale: string;
    providerCode: string;
    mapped: boolean;
    support: "supported" | "unverified" | "unsupported";
    warnings: { code: string; message: string }[];
  };
  locales: {
    locale: string;
    providerCode: string;            // the code the provider receives
    mapped: boolean;                 // true when localeMap set providerCode
    support: "supported" | "unverified" | "unsupported";
    glossary: boolean;
    formality: boolean;
    warnings: { code: string; message: string }[];
  }[];
}
```

`result.locales` est absent quand la configuration n'a pas pu être chargée, pour un fournisseur inconnu et pour `provider: { id: "none" }`.

### Retour dans le terminal [#retour-dans-le-terminal]

<AvailableFrom version="0.12.0" />

Pendant son exécution, `doctor` affiche une ligne sur stderr, que `--quiet` supprime : `checking the setup`, `checking the setup and fetching the provider's language list` avec `--live`, `describing the data flow` avec `--data-flow`, ou `scanning the source for literals` avec un nombre de fichiers avec `--literals`. Le rapport reste sur stdout. Voir [Sortie dans le terminal](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#sortie-dans-le-terminal).

## Codes de sortie [#codes-de-sortie]

| Code | Signification |
| --- | --- |
| `0` | aucune vérification n'a échoué (un `warn` sort aussi avec `0`) |
| `1` | au moins une vérification a échoué, y compris une locale non prise en charge ; avec `--literals`, un littéral trouvé ou un fichier non analysable |
| `2` | impossible de s'exécuter : une erreur d'usage ou un chemin `--config` explicite qui n'existe pas |

Une configuration que la recherche ne trouve pas, ou qui échoue à la validation, est une vérification échouée (sortie `1`), puisque la signaler est justement le rôle de la commande. Voir [le contrat des codes de sortie](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#codes-de-sortie).

## Voir aussi [#voir-aussi]

- [`verbatra init`](https://verbatra.kreitz-webdev.de/fr/docs/cli/init.md) crée la configuration et le `.env.example` que `doctor` valide.
- [`verbatra check`](https://verbatra.kreitz-webdev.de/fr/docs/cli/check.md) est le contrôle de dérive à lancer une fois la configuration saine.
- [Le fichier de configuration](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md) documente chaque clé que `doctor` valide.
- [Fournisseurs](https://verbatra.kreitz-webdev.de/fr/docs/providers.md) liste la variable de clé d'API que lit chaque fournisseur.
- [Prise en charge des langues](https://verbatra.kreitz-webdev.de/fr/docs/language-support.md#vérifier-la-prise-en-charge-avant-une-exécution) liste les tables de langues qu'utilise la vérification Locale support.
