octobercms/october · warning · Exception
[!!] Missing key for english [{$key}] in [{$englishPath}]
Error message
[!!] Missing key for english [{$key}] in [{$englishPath}] What it means
The october:util refit lang utility (OctoberUtilRefitLang::utilRefitLang) converts legacy nested PHP language files (lang/<locale>/<file>.php) into per-locale JSON files (lang/<locale>.json) keyed by the English source string. For each key found in a non-English locale it does array_get($englishArr, $key); when the English source file has no such key, the JSON key cannot be derived and an Exception '[!!] Missing key for english ...' aborts the run.
Source
Thrown at modules/system/console/OctoberUtilRefitLang.php:188
$fileName = 'lang.php';
}
$englishPath = "{$basePath}/lang/en/{$fileName}";
$englishArr = include($englishPath);
$legacyPath = "{$basePath}/lang/{$lang}/{$fileName}";
$legacyArr = include($legacyPath);
$newPath = "{$basePath}/lang/{$lang}.json";
$newArr = [];
if (file_exists($newPath)) {
$newArr = json_decode(file_get_contents($newPath), true);
}
$english = array_get($englishArr, $key);
if (!$english) {
throw new Exception("[!!] Missing key for english [{$key}] in [{$englishPath}]");
}
$translated = array_get($legacyArr, $key);
if (!$translated) {
$this->comment("[{$lang}] Missing key [{$key}] in [{$legacyPath}]");
return;
}
$newArr[$english] = $translated;
File::put($newPath, $this->refitLangJsonEncode($newArr));
$this->comment("[{$lang}] → {$english}:{$translated}");
if ($lang === 'en') {
$this->comment(PHP_EOL);
$this->refitFinalMessage = "<?= __(\"{$english}\") ?>";
}View on GitHub (pinned to b608633a7e)
Solutions
- Add the missing key(s) to the English file named in the message (lang/en/<file>.php) — the message includes the key and path
- Or delete the orphaned key(s) from the offending locale file if the string is obsolete
- Re-run php artisan october:util refit lang; each fixed file proceeds until the next missing key, so repeat until it completes
Example fix
// before: lang/fr/validation.php contains 'custom.name' but lang/en/validation.php does not
// after: add the English source so the JSON key can be derived
// lang/en/validation.php
return [
// ...
'custom' => ['name' => 'Name'],
]; Defensive patterns
Strategy: validation
Validate before calling
$en = include "$basePath/lang/en/{$fileName}.php";
$loc = include "$basePath/lang/{$lang}/{$fileName}.php";
$missing = array_diff(array_keys(array_dot($loc)), array_keys(array_dot($en)));
if ($missing) {
// fix lang/en first: ' . print_r($missing, true)
} Prevention
- Keep English files the canonical key set; add new keys there first
- Run a key-diff check in CI before executing refit lang on translation trees
- Rename keys in all locales together, never English alone
When it happens
Trigger: Running php artisan october:util refit lang when lang/<locale>/<file>.php contains keys that do not exist in lang/en/<file>.php (translator added keys only to their locale, or English keys were renamed), or the English file is missing entirely.
Common situations: Contributed translations drifting ahead of the English base; plugins merged from forks with divergent lang trees; refactoring that renamed English keys but not the translations.
Related errors
- Display name cannot be empty.
- Media tags can only be processed for front-end requests.
- There are no commands defined in the "util" namespace.
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/1122fb6e5c34b175.
Report an issue: GitHub.