# How to Read Validation Badges

> What each validation badge means (Missing, Same, Param, Length, ICU, Guarded, and Malformed) and how to fix them, including the one-click wrench autofix.

Source: https://stringlane.app/docs/read-validation-badges
Last updated: 2026-08-21

StringLane validates all translations whenever a project loads and after each edit. Problems appear as inline badges on the affected cell. Hover over a badge for a tooltip with the full error message.

![Detail pane for a key with two missing translations: a red 2 MISSING chip in the header, MISSING badges on the German and Japanese cards, the per-locale character-width preview below, and red and amber dots against keys in the sidebar](/docs-screenshots/validation-badge-variety.webp)

## Badge types

Seven badges can appear on a cell. Colour indicates severity — red is an error, yellow a warning — but the badges are distinguished by their **label**, not their colour, so they stay readable if you can't separate the two hues.

| Badge | Severity | Means |
|---|---|---|
| **Missing** | error | No value in this locale |
| **Param** | error | Placeholder missing or wrong |
| **ICU** | error | Invalid ICU syntax |
| **Malformed** | error | Placeholder syntax is broken |
| **Same** | warning | Identical to the base locale |
| **Length** | warning | Over the character budget |
| **Guarded** | warning | A protected term was changed |

---

### Missing (red)

The key exists in the base locale but not in this target locale file. The cell is empty and reads *Click to translate…*.

**Fix:** Type a translation manually, or click ✨ to translate with AI. To fill a whole locale, use the **✨ Translate…** popover in the sidebar footer. To clear missing translations across the whole project in one pass, use **Translate all missing with AI** from the [Command Palette](/docs/use-command-palette).

---

### Same (yellow)

The translation is identical to the base locale value. This usually means the key hasn't been translated yet: the source value was copied but not replaced.

**Fix:** Check if the string should actually be translated. Proper nouns (brand names, product names), URLs, and technical identifiers often should be the same in all locales: use [Guarded Words](/docs/configure-guarded-words) to mark these intentionally. If it should be translated, click ✨ or edit the cell.

---

### Param (red)

A placeholder present in the base locale is missing from, or wrongly spelled in, the target translation. For example, the base has `Hello, {name}!` but the Spanish translation is `¡Hola!` with no `{name}`.

**Fix:** When StringLane can work out the correct string on its own, a 🔧 **wrench** button appears next to the badge — click it and the fix is applied instantly, with no AI call and no cost. Otherwise, add the missing placeholder yourself; the tooltip names exactly which one is missing or extra. See [How to Fix Placeholder Mismatches](/docs/fix-placeholder-mismatches).

---

### Malformed (red)

The placeholder syntax itself is broken — an unclosed `{`, a stray brace, a `%` specifier that isn't valid for the format. This is distinct from **Param**, where the placeholders are well-formed but the wrong set.

**Fix:** The 🔧 **wrench** button repairs the common cases deterministically. Click it, or correct the syntax by hand.

---

### Length (yellow)

The translation exceeds the character budget for that key. The budget is the key's **Max length**, set in the metadata panel or in **Settings → Project → Key Constraints** — one value, shown in two places. On ARB it is stored as `x-max-length` in the `@key` block; on the other formats it goes to [`.stringlane/metadata.yaml`](/docs/key-metadata-storage).

The **character-width preview** under the detail pane shows every locale as a bar against the budget, so you can see how close the others are before one tips over.

**Fix:** Shorten the translation. See [How to Add Key Descriptions and Limits on Any Format](/docs/annotate-keys-any-format) for setting the limits.

---

### ICU (red)

The translation contains invalid ICU MessageFormat syntax. Common causes: unmatched braces, missing `other` plural category, or a malformed `select` clause.

**Fix:** Click the badge for the specific error, then edit the cell using the ICU Format Helper or Visual ICU Editor. See [Working with ICU Plurals and Select Forms](/docs/working-with-icu-plurals).

---

### Guarded (yellow)

A term marked as a guarded word (brand name, product term) has been translated or modified in this target locale. The translation differs from the base locale value for that protected term.

**Fix:** Re-translate the key with ✨: the AI will respect the guarded word constraint. Or manually restore the guarded term to its original form.

## Two checks that appear only in the Issues panel

Not every validation result is a cell badge. Two show up as rows in the [Issues Panel](/docs/use-issues-panel) (**⌘J**):

**Literal # in plural** (warning). An ICU plural body contains a bare `#`. In most ICU implementations `#` is substituted with the number — but **Flutter's `gen-l10n` does not do this**, so the string ships with a literal `#` on screen. If you write ARB for Flutter, this is the check that catches it. Each row offers **Fix with AI**, which tries a deterministic rewrite (`#` → the plural variable) before falling back to the model.

**Missing plural category** (error). The target language requires a CLDR plural category the translation does not provide — Ukrainian and Polish need `few` and `many`, Arabic needs all six. See [Working with ICU Plurals](/docs/working-with-icu-plurals).

## Row-level indicators

The key sidebar shows a per-key dot summarising the worst badge in any locale for that key:

- **Red dot**: at least one error-level badge (Missing, Param, ICU, Malformed)
- **Amber dot**: at least one warning-level badge (Same, Length, Guarded), no errors

The status bar carries the project-wide totals — translation percentage, locale and key counts, and error and warning chips you can click to filter.

Use the **Issues only** filter in the sidebar (or **⌘⇧I**) to show only keys with any badge, and the [Issues Panel](/docs/use-issues-panel) (**⌘J**) to see every problem in the project as one row per (locale, issue), with click-to-jump and per-row Fix-with-AI actions. **Fix all with AI** at the foot of the panel sweeps every addressable row in one pass.
