---
title: "systhema doctor"
description: "Project health checks, auto-fix, the nudge and the branded header."
requested_language: hu
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/hu/cli/doctor
version: unreleased (main)
docs_index: https://docs.systhema.app/hu/llms.txt
---
> This page isn't translated yet. Showing English.


One command to diagnose project health and auto-fix what's safely fixable. It runs a registry of checks, reports findings grouped by severity (errors → warnings → info), and exits with status `1` if any error-severity diagnostic is present.

```bash
systhema doctor                          # run all checks, print a grouped report
systhema doctor --fix                     # interactively apply fixable findings
systhema doctor --fix --yes --no-git-check # CI-friendly: skip prompts + git check
systhema doctor --json                    # machine-readable output (no mutation)
systhema doctor --only peer-deps          # run a single check (repeatable)
systhema doctor --skip version-drift      # skip a check (repeatable)
```

## Options

<!-- generated:cli-flags doctor -->

| Flag             | Description                                  | Default |
| ---------------- | -------------------------------------------- | ------- |
| `--fix`          | Apply fixable issues (interactive, git-safe) | `false` |
| `--force`        | Allow a dirty working tree when fixing       | `false` |
| `--json`         | Output diagnostics as JSON                   | `false` |
| `--no-git-check` | Skip git repo check (CI mode)                | `true`  |
| `--only <id>`    | Run only this check (repeatable)             | `[]`    |
| `--skip <id>`    | Skip this check (repeatable)                 | `[]`    |
| `-y, --yes`      | Skip confirmation prompts                    | `false` |

<!-- /generated -->

### Flag behavior

- `--fix` — apply auto-fixable findings. Runs a git-safety preflight (clean working tree, or `--force` / `--no-git-check`), then confirms each fix category interactively before delegating to the existing engines. Report-only findings print a fix hint instead.

## Checks

<!-- generated:doctor-checks -->

| Check                       | What it checks                                 | Speed  | Auto-fix                            |
| --------------------------- | ---------------------------------------------- | ------ | ----------------------------------- |
| `ai-config`                 | AI assistant config                            | `fast` | no                                  |
| `analytics-config`          | Analytics config                               | `fast` | no                                  |
| `artifacts-config`          | Config & artifacts                             | `fast` | yes; `sync`                         |
| `cloudflare-config`         | Cloudflare config                              | `fast` | no                                  |
| `fluid-spacing-breakpoints` | Fluid spacing above the top breakpoint         | `fast` | no                                  |
| `legacy-tokens`             | Legacy tokens                                  | `fast` | yes; `migrate-tokens`               |
| `lexical-patch`             | Lexical admin patch                            | `fast` | yes; `lexical-patch`                |
| `localization-policy`       | Content localization field policy              | `fast` | no                                  |
| `localize-status-schema`    | Per-locale publication status                  | `slow` | no                                  |
| `missing-tokens`            | Missing tokens                                 | `fast` | yes; `token-migration:${c.version}` |
| `obfuscate-build-step`      | Class obfuscation wiring                       | `fast` | no                                  |
| `package-manager-pin`       | pnpm version pin                               | `fast` | yes                                 |
| `peer-deps`                 | Peer deps                                      | `fast` | yes                                 |
| `pending-db-renames`        | Database table names                           | `slow` | no                                  |
| `pending-migrations`        | Upgrade plan                                   | `fast` | yes                                 |
| `replaced-proxy`            | Customised src/proxy.ts replaced by an upgrade | `fast` | no                                  |
| `stale-references`          | Token references                               | `fast` | yes; `sync`                         |
| `stale-token-artifacts`     | Token artifact cache                           | `fast` | yes; `sync`                         |
| `ui-patch`                  | Admin language cache patch                     | `fast` | yes; `ui-patch`                     |
| `version-drift`             | CLI version                                    | `slow` | no                                  |

<!-- /generated -->

### Check behavior

- ---------------------------: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

- `pending-migrations`: The project is behind the installed CLI, or sits on the CLI's version with a codemod that still applies (an interrupted upgrade). Counts what `systhema upgrade` would run — a post-upgrade data hook is only counted on a real version step, since a re-run cannot tell whether it already ran.

- `pending-db-renames`: _(payload)_ Legacy Systhema table names still live in the database — connects read-only via `DATABASE_URI` (Postgres/SQLite) and compares the live catalog against the expected names. Catches projects that upgraded past the release window the rename shipped in, where the next schema push would hang on Drizzle's interactive create-or-rename prompt. See [Database migrations](https://docs.systhema.app/hu/payload/database/migrations.md).

- `localize-status-schema`: _(payload)_ The database and the config disagree about where `_status` lives. Per-locale publishing is on by default whenever `locales` is configured, which moves `_status` out of the shared column on `pages`, `posts` and `components` and into their `_locales` siblings. Connects read-only via `DATABASE_URI` (Postgres/SQLite) and reads the live columns, so it also catches the inverse: a project that opted out of `localizeStatus` against a database that already moved. See [Per-locale publishing](https://docs.systhema.app/hu/payload/localization/per-locale-publishing.md).

- `package-manager-pin`: `package.json` has no exact pnpm `packageManager` (missing, or floating like `pnpm@10`), or pins a pnpm that cannot install `pnpm-lock.yaml`. All pnpm releases since 9 write `lockfileVersion: '9.0'`; the patch and package-extension hashes tell them apart. pnpm 9 writes base32/md5, pnpm 10 sha256 under `hash:`, pnpm 11 and later a bare sha256 per patch, and a frozen install on another format fails with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`. A lockfile without those hashes works with any of them. When `package.json` has a `pnpm` field, pnpm 11 and later are flagged too: they ignore that field, which silently drops its overrides, patches and build allowlist. A pnpm 11 lockfile next to such a field is reported as installable by no pnpm. A pnpm 12 or later pin also needs the lockfile to record that exact version; until `pnpm install` writes it, a frozen install fails with `ERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE`. Silent without a `pnpm-lock.yaml` at the project root, so a workspace sub-project is not checked.

- `stale-token-artifacts`: The installed `@systhemaui/core` does not carry this project's tokens — `.systhema/artifacts/tokens/*.json` and `node_modules/@systhemaui/core/dist/tmp/tokens/*.json` disagree (differing bytes, a missing file, or a phantom file the project no longer defines). Typically an install that replaced the package after the last `sync`; token-derived option lists (themes, layout backgrounds) come from the package defaults until the mirror is refreshed. Silent when the project has no synced artifacts or `@systhemaui/core` is not installed.

- `ai-config`: _(payload)_ AI assistant misconfiguration across the merged dotenv set (`.env`, `.env.development`, `.env.production`, `.env.local`; later overrides earlier) — unknown `SYSTHEMA_AI_PROVIDER`, a keyed provider without `SYSTHEMA_AI_API_KEY`, or `openai-compatible` without `SYSTHEMA_AI_BASE_URL` / `SYSTHEMA_AI_MODEL`.

- `analytics-config`: _(payload)_ Analytics dashboard misconfiguration across the same merged dotenv set — unknown `SYSTHEMA_ANALYTICS_PROVIDER`, or a provider missing its required variables (site id, API key, Matomo host, GA4 service-account email/private key, Umami Cloud key or self-hosted host + username/password).

- `cloudflare-config`: _(payload)_ [Cloudflare integration](https://docs.systhema.app/hu/payload/cloudflare.md) misconfiguration across the same merged dotenv set — a Global API key without its account email (or vice versa), both `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_API_KEY` set at once (ambiguous), or a non-boolean `SYSTHEMA_CLOUDFLARE_AUTO_PURGE`.

- `stale-references`: The agent-facing TOON references at `.systhema/references/tokens/` are missing, or `_index.toon` says a different `@systhemaui/core` wrote them than the one installed. Reference generation is the last step of `sync` and is deliberately non-fatal, so a failure there leaves last version's values and serialization in place with only a warning in the scrollback. Silent when the project has no synced artifacts, when `@systhemaui/core` is not installed, or when the stamp cannot be read.

- `obfuscate-build-step`: `optimization.obfuscateClasses` is enabled in `systhema.config` but no `package.json` script chains `systhema-core obfuscate` after the build (the flag is inert on its own — silent no-op), and/or it is enabled on a PayloadCMS project at all (class obfuscation is prerender-only; the post-build pass refuses to run there).

- `fluid-spacing-breakpoints`: The `spacing` config uses a fluid `%screen%` rule, but some configured breakpoint above the narrowest `responsiveSizing` mode has no mode of its own (neither exported nor declared in `customTokens.responsiveSizing`) — so that band keeps scaling the nearest lower breakpoint's ratios, without any bound at all above the widest declared mode.

- `localization-policy`: A Payload project with locales enabled that has not declared `localization.policy`. Until it does, content localization runs the legacy name-allowlist policy: form notification recipients, per-page `noindex` and redirect targets are shared across every locale.

- `replaced-proxy`: `src/proxy.ts` is a stock Systhema gateway while `src/proxy.ts.bak` matches no proxy Systhema shipped: the likely trace of an upgrade before 1.7.5 that replaced a customised proxy with no managed-files ledger entry. Any rate limiting, CSP or security headers the backup set are no longer running.

Report-only findings (`artifacts-config`'s missing-config case, `pending-db-renames`, `localize-status-schema`, `ai-config`, `analytics-config`, `cloudflare-config`, `obfuscate-build-step`, `fluid-spacing-breakpoints`, `localization-policy`, `replaced-proxy`, `version-drift`) print a hint rather than mutating anything.

`artifacts-config`, `stale-token-artifacts` and `stale-references` deliberately share one fix grouping: all three are cured by a single `systhema-core sync`, so when several fire the report collapses them to one entry and `--fix` prompts, and syncs, once.

`pending-db-renames`, `localize-status-schema` and `version-drift` are `slow` checks (two database connections and a registry lookup): they run in `systhema doctor`, but never in the one-line nudge other commands print. Both database checks stay silent when the database is unreachable or `DATABASE_URI` is unset, on MongoDB, and when the tables are not there yet; neither creates a missing SQLite file.

## The nudge

Other commands — `info`, `upgrade --dry-run`, `create`, and the proxied `sync` / `copy-files` / `generate-types` / `migrate-tokens` — run only the fast (local) checks and print a single one-line nudge toward `systhema doctor --fix` when a project has fixable issues. The nudge never networks (the slow `version-drift` check is excluded), never throws, and is throttled by a 6-hour per-project cache at `~/.systhema/doctor-cache.json`.

Silence it with any of:

- `SYSTHEMA_NO_DOCTOR=1` — opt out entirely.
- `CI` — automatically suppressed in CI environments.
- `--json` — suppressed alongside any JSON output.

## Branded header

The SYSTHEMA wordmark that appears above interactive command output is gated on stdout being a TTY. It is suppressed automatically when output is piped, redirected, or captured (e.g. by an agent), in CI, in `--json` mode, or when `SYSTHEMA_NO_BANNER=1` is set. When run interactively — even with flags like `--fix` or `--json` omitted — the header is shown as normal. No flag is needed to control this: TTY detection handles it.
