> For the complete documentation index, see [llms.txt](/llms.txt)

# Migration diagnostics

## Migration diagnostics — from Stainless

[Migrating from Stainless](/docs/migrate-from-stainless) translates a `stainless.yml` into a
`glotto.yml`. It is **non-destructive and never silently drops anything**: every key it could not
carry over is reported, so the migration report is the checklist of what still needs a human.

| Code | Severity | Meaning |
| --- | --- | --- |
| `GLOTTO_MIGRATE_STAINLESS_UNMAPPED` | warning | A key in your `stainless.yml` has no `glotto.yml` equivalent, so it was **dropped rather than guessed at**. The path names the key (nested paths are reported in full). Review each one against the [migration guide](/docs/migrate-from-stainless) — some are Stainless-specific and safely gone, others have a different Glotto mechanism worth re-expressing by hand. |
| `GLOTTO_MIGRATE_STAINLESS_PLACEHOLDER` | warning | A **required** `glotto.yml` field could not be derived from the Stainless input, so the migrator wrote a placeholder value to keep the output well-formed. Replace every placeholder before running `glotto generate` — the config is not usable until you do. |

Both are warnings rather than errors because the migration itself succeeded; they describe work
remaining, not a failure. Together they are the first Glotto diagnostics most migrating teams see.

## Migration diagnostics — from Fern

[Migrating from Fern](/docs/migrate-from-fern) translates a `fern/generators.yml` into a
`glotto.yml`. Where the Stainless migrator's report is binary — carried over, or dropped — this one
gives **every** input key one of four verdicts, because several Fern *knobs* are Glotto
*guarantees*: reporting those as a loss would say you are giving up a property at the moment you are
gaining a stronger version of it.

| Code | Severity | Meaning |
| --- | --- | --- |
| `GLOTTO_MIGRATE_FERN_MAPPED` | info | The key was translated. The message names the `glotto.yml` key it became. |
| `GLOTTO_MIGRATE_FERN_GUARANTEED` | info | **You are not losing this.** Glotto provides the property unconditionally, so there is nothing to configure — the message names the guarantee (open enums, unknown-field preservation, the emitted test suite). |
| `GLOTTO_MIGRATE_FERN_NOT_HONORED` | info | A Fern *emission-shape* knob Glotto answers differently on purpose (`noSerdeLayer`, the `pydantic_config` block, `union: v0\|v1`, …). Honoring it would mean re-implementing Fern's emitter, so it is a deliberate non-goal rather than a gap. |
| `GLOTTO_MIGRATE_FERN_UNMAPPED` | warning | Genuinely no `glotto.yml` home, reported at its precise dotted path. This is the list that needs your attention. |
| `GLOTTO_MIGRATE_FERN_PLACEHOLDER` | warning | A **required** `glotto.yml` field your Fern config cannot supply (your organization details live in `fern.config.json`, your environments in the API definition). Replace every placeholder before running `glotto generate`. |
| `GLOTTO_MIGRATE_FERN_IGNORE` | info | A `.fernignore` entry. Fern *freezes* a listed file; Glotto [three-way-merges](/docs/custom-code) instead, so the entry is reported with the construct that replaces it and no file is written. |
| `GLOTTO_MIGRATE_FERN_NAME_UNPINNED` | warning | Under `--preserve-names`, an emitted member name that could not be pinned to the Fern spelling — a reserved word (pinning it would emit code that does not compile), an ambiguous acronym split, the client class name, or a transparent-DTO engine. Names **both** spellings so nothing is left silently divergent. |
| `GLOTTO_MIGRATE_FERN_GROUP_AMBIGUOUS` | error | Your project declares several generator groups and no `default-group`, so there is nothing to migrate without a choice. Re-run with `--group <id>`; no file is written. |
| `GLOTTO_MIGRATE_FERN_DOCS_PLACEHOLDER` | warning | The docs half's sibling of `GLOTTO_MIGRATE_FERN_PLACEHOLDER`: a **required** field of the migrated `docs` block your `fern/docs.yml` cannot supply. Today that is a `docs.versions[]` spec snapshot — Fern's `versions[].path` names that version's *docs config*, not a spec — so each entry is written with a clearly-marked `TODO` source for you to replace. |
| `GLOTTO_MIGRATE_FERN_DEFINITION_INPUT` | error | This is a Fern **Definition** project, not an OpenAPI one. Export the API first (`fern api export --openapi`) and re-run against the exported document. |

The two `error` codes stop the migration and write no output — half-migrating either case would
produce a config that validates but generates the wrong SDKs.
