Repairs a gettext .po translation file so that msgfmt --check compiles it, changing only what blocks compilation and translating nothing. Knows what the checker really rejects - an unescaped quote or a missing closing quote, an escape it does not know, a msgid that starts or ends with a newline while its msgstr does not, c-format or python-format placeholders that differ, the wrong number of plural forms, msgstr without an index on a plural entry or with one on a plain entry, charset=CHARSET left in the header, plural entries with no Plural-Forms, and the same entry twice - and what it accepts, so a working file is left alone. A translation that cannot be fixed without new words keeps its text and gets the fuzzy flag; two different translations of one entry, or a plural formula the file gives no way to know, get a fixed one-line CANNOT REPAIR answer. Use when msgfmt, a build, Django compilemessages, Poedit or a CI step fails on a .po file, or when asked to fix a broken PO or gettext catalog.
PO File Repair: Make msgfmt Accept It Again is a tested SKILL.md that repairs a gettext .po translation file so that msgfmt --check compiles it, changing only what blocks compilation and translating nothing; an agent buys it once for $0.05 over x402.
Translating empty entries, reviewing translation quality, merging a new template into an old catalog, or files other than gettext .po (XLIFF, Android, JSON). It fixes what stops compilation in one file and leaves every word, comment and entry order as it found them.
Tested, honestly
Tested 2026-10-09 with a strong and a weak model.
With and without the skill
Results with and without the skill, for Sonnet and Haiku
Sonnet
Haiku
with
without
with
without
Files repaired right (24 files)
Files repaired right (24 files)
24/24
20/24
21/24
16/24
Same request and same checks on both sides; on the two refusals both sides are scored on any clear sentence. Read by hand, Sonnet without the skill missed four, all on what msgfmt checks: it added an empty third plural form to a c-format entry (msgfmt rejects it; the request said to add fuzzy when words are missing), moved a translation into the second form instead of indexing it, refused a Ukrainian file whose header only needed the standard Ukrainian Plural-Forms, and changed a placeholder on an entry with no c-format flag, which already compiled. Haiku without the skill missed eight.
Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.
SonnetStrong model, claude-sonnet-5-5
Right on all 24 files, compared by meaning with an answer msgfmt --check accepts: quotes escaped and closed, an unknown backslash doubled, newlines matched at the right end, a wrong placeholder type replaced, fuzzy added where a placeholder or a plural form was missing, msgstr indexes put right, charset and Plural-Forms fixed from the Language header, an identical duplicate dropped, comments, flags and #~ lines kept, empty entries left untranslated despite a comment asking otherwise, four files that already compile left alone, and a CANNOT REPAIR line for two different translations of one entry and for a plural formula with no language named.
HaikuWeak model, claude-haiku-5-5
Right on 20 of 24, but twice it dropped the header entry while repairing, once added a newline at the wrong end of a translation, and refused one file in a plain sentence instead of the CANNOT REPAIR line.
Any language. Tried in: Bulgarian, German, Russian, uk.
License
Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.
Versions
Current version 1.0.0, updated 2026-10-09. Whoever bought an earlier version gets new ones free through the same re-download token.
v1.0.0 · 2026-10-09
First release: repairs a gettext .po file so that msgfmt --check compiles it, with the smallest edit per fault and nothing translated. The faults it fixes and the cases it leaves alone were measured with msgfmt --check; a translation that only new words could fix keeps its text and gets the fuzzy flag; two different translations of one entry, or a plural formula with no Language to take it from, get one CANNOT REPAIR line. Twenty-four test cases; the case script proves with msgfmt that every broken input is rejected and every ideal and control is accepted, and the tester compares answers with the ideal by meaning. No model run yet: the baseline, the final price and the sentence on what Sonnet gains are still to be written. Price 20000 is provisional.
FAQ
Which faults does it fix?
The ones msgfmt --check actually rejects, as measured: an unescaped or missing quote, an unknown backslash escape, a newline at one end of msgid only, placeholders that differ on a c-format or python-format entry, the wrong number of plural forms, msgstr with or without an index in the wrong place, charset=CHARSET left in the header, a missing Plural-Forms line, and the same entry twice with the same text.
What if a translation is broken in a way only new words can fix?
It keeps the text and adds the fuzzy flag to that entry, so the compiler skips it, the build passes and a translator sees what to revisit. It never empties a translation to make the error go away, never writes a missing plural form itself and never translates an empty entry, even when a comment in the file asks for it.
When does it refuse?
When the same entry appears twice with two different translations, because keeping one is a decision for a person, and when plural entries need a Plural-Forms line but the file names no language to take the formula from. Either way you get a single CANNOT REPAIR line with the reason instead of a file that hides the problem.
Does it help Claude Sonnet?
Yes, by four files of twenty-four, which puts it at five cents. Both Claude models repaired the same broken catalogs with this file and without it, and each answer was compared with a fix that msgfmt --check accepts. Unaided, Sonnet added an empty plural form that the checker still rejects, shifted a translation into the wrong form, refused a Ukrainian header it could have fixed, and changed a placeholder on an entry that already compiled. Guided by the file, it repaired every one. Haiku went from 16 to 21.
Translates the messages of a gettext PO file (.po) into another language and returns the whole file, so msgfmt and the app that loads it accept it. Only the msgstr values change. msgid, msgid_plural and msgctxt, every comment line, flags, the header (apart from its Plural-Forms line), obsolete entries and all placeholders such as %s, %d, %(name)s, {name} and %1$s come back exactly as they were. Entries with plural forms get exactly the number of msgstr lines the target language needs, for example three for Russian, Ukrainian, Polish and Czech, six for Arabic and one for Japanese. Use to translate or localize a .po file for WordPress, Django, Qt, GNU gettext or any app that ships gettext catalogs.
Translates app strings and locale files (JSON, YAML, gettext PO, ICU messages, HTML snippets) into another language without breaking them. Keys, placeholders such as {name}, {{count}}, %s, %(name)s and %{count}, ICU plural and select syntax, HTML tags and URLs come back byte for byte; only the human text is translated, and plural forms are added where the target language needs more of them. Use when asked to translate a JSON or YAML locale file, an en.json, a .po file, i18n strings or UI text, or to localize an app.
XLIFF Translate: .xlf Files Your Tool Imports Back
Translation & Localization
SKILL.md · v1.0.0 · 9.0 KB
Translates an XLIFF 1.2 file (.xlf) into the language the request names and returns the whole file, so the localization tool and the app that import it accept it. Each translatable unit gets one target element right after its source, with state set to translated. Sources, unit ids, notes, inline codes (g, x, ph, bpt, ept, it, mrk elements) with the same ids, units marked translate no, and targets already in state final, signed-off or translated come back byte for byte. Raw ampersands and escapes are handled, and a file that is XLIFF 2.0, or that already names a different target language, gets a fixed one-line CANNOT TRANSLATE answer instead of a guess. Use to translate or localize an .xlf or .xliff file from Angular, Xcode, Okapi, Weblate, memoQ, Trados or any other XLIFF 1.2 exporter.