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

# Diagnostics reference

**Looking up a `GLOTTO_*` code?** Jump to [config diagnostics](/docs/diagnostics-config#config-diagnostics), [migration diagnostics](/docs/diagnostics-migrations#migration-diagnostics-from-stainless), or
[fatal errors](/docs/diagnostics-fatal#fatal-errors). Every code Glotto can emit has a row in this
reference.

Glotto's **SDK-readiness ruleset** describes spec shapes that produce awkward or incomplete
SDKs — missing `operationId`s, anonymous schemas, undeclared errors or auth, missing
idempotency advertisement. Resolving them is the cheapest way to raise the quality of every
generated SDK at once, and the rule ids below are the ones
[`diagnostics.rules`](/docs/glotto-yml-project-settings#diagnostics) accepts.

**Where you see them:** `glotto generate` prints every finding for your spec, alongside any
problems in your `glotto.yml`. The ruleset runs as part of generation, so there is nothing separate
to run and nothing to remember — if your spec has a readiness problem, you hear about it the next
time you generate.

This page enumerates every rule in that ruleset, then links to every coded diagnostic Glotto reports.
Each finding carries a Spectral-compatible shape:

```json
{ "rule": "operation-id-missing", "severity": "error", "path": ["paths", "/pets", "post"], "message": "…" }
```

## Severities

Every rule is `error` or `warning`, and the two mean different things: an **error** blocks
correct SDK generation, a **warning** is a quality or developer-experience problem in the SDK
that results. A rule's default severity is listed with it below, and
[`diagnostics.rules`](/docs/diagnostics-config#tuning-diagnostics) overrides it.

### Release-gating guidance

Treat the two severities as a release ladder:

- **Resolve every `error` before your first published release** — errors block correct SDK
  generation (e.g. a method with no name).
- **Resolve every `warning` before `1.0`** — warnings are quality and DX issues that are cheap
  to fix early and awkward to change after consumers depend on the SDK.

To turn the second rung into a hard gate, cap the allowed warning count with
[`diagnostics.max_warnings`](/docs/diagnostics-config#tuning-diagnostics), then ratchet it down toward zero on the way
to `1.0`.

## Errors

Errors block high-quality generation and should be fixed first.

### `operation-id-missing`

**Severity:** error · **Path:** `paths.<path>.<method>`

An operation has no `operationId`. SDK method names derive from `operationId`, so without one
the method name has to be synthesized from the path and verb — producing awkward, unstable names.

**Fix:** give every operation a unique, descriptive `operationId` (e.g. `listPets`, `createPet`).

## Warnings

Warnings don't block generation but degrade SDK quality, docs, or ergonomics.

### `operation-undescribed`

**Severity:** warning · **Path:** `paths.<path>.<method>`

An operation has neither a `summary` nor a `description`. The generated SDK reference and the MCP
tool descriptions both draw on this prose, so its absence yields thin docs and lower-quality MCP
tool definitions.

**Fix:** add a `summary` (and ideally a `description`) to each operation.

### `inline-object-schema`

**Severity:** warning · **Path:** `paths.<path>.<method>.requestBody|responses.<code>.content.<mediaType>.schema`

A request body or response uses an **anonymous inline object schema** (a `type: object` /
`properties` block, or an array of one) instead of a `$ref` to a named `components.schemas`
entry. Inline objects generate unnamed, un-reusable SDK types.

**Fix:** hoist the schema into `components.schemas` and reference it with `$ref`.

### `no-error-response`

**Severity:** warning · **Path:** `paths.<path>.<method>.responses`

An operation declares no `4xx`, `5xx`, or `default` response, so the SDK cannot model the errors
the endpoint can return — callers get untyped failures.

**Fix:** declare the error responses the operation can produce (a shared `default` error response
is a good baseline).

### `mutation-no-idempotency-key`

**Severity:** warning · **Path:** `paths.<path>.post`

A `POST` operation does not advertise an `Idempotency-Key` header parameter. Glotto can
auto-generate and inject idempotency keys so retries of a mutation are safe — but only when the
endpoint accepts the header.

**Fix:** add an `Idempotency-Key` header parameter to the operation (or to the path item, shared
across its operations). See [Idempotency keys](/docs/idempotency-key) for the concept.

### `required-header-param-not-client-scoped`

**Severity:** warning · **Path:** `paths.<path>.<method>`

An operation declares a **required header parameter** that only a minority of the document's
operations declare at all. Every generated SDK takes such a header as a normal call argument, so
those are unaffected — but a target whose only home for it is *client-scoped* cannot express a
value that varies from one operation to the next. The generated Terraform provider is the case in
point: the header becomes a `Required` argument on the `provider "glotto"` block, and that single
value is sent on **every** request the provider makes.

A header the whole API requires (a tenant id, an API-version date) is not flagged — one
provider-block value is exactly right for it.

**Fix:** if the value really is constant for the whole client, declare the header on every
operation that accepts it — or set it once with `auto_populate` in
[`glotto.yml`](/docs/glotto-yml), which stamps it into the request and removes it from the
generated signatures. If it genuinely varies per call, keep using it from the SDKs (where it is a
per-call argument) and expect the Terraform provider to send one fixed value.

### `no-security-defined`

**Severity:** warning · **Path:** *(document root)*

The API declares no security at all — no `components.securitySchemes`, no root `security`, and no
per-operation `security`. The generated SDK has nothing to wire authentication to.

**Fix:** declare a security scheme under `components.securitySchemes` and apply it via a root or
per-operation `security` requirement. See [Authentication](/docs/authentication).

## Coded diagnostics

Every stable `GLOTTO_*` code remains documented in this reference, grouped by where it is raised:

- [Configuration and validation diagnostics](/docs/diagnostics-config)
- [Migration diagnostics](/docs/diagnostics-migrations)
- [Fatal configuration, spec, and transform diagnostics](/docs/diagnostics-fatal)
- [SDK generation diagnostics](/docs/diagnostics-sdk-generation)
- [Runtime diagnostics raised by generated SDKs](/docs/diagnostics-runtime)

## Roadmap

Importing your existing Spectral ruleset, custom rules, one-click autofixes, and inline editor
(LSP) diagnostics are tracked as follow-ons to the linter — they are not available yet.
Per-rule severity overrides and suppression, and a release-gating warning budget, **are**
available today via the [`diagnostics` config block](/docs/diagnostics-config#tuning-diagnostics).
