symfony/translation · error · InvalidResourceException
The " " message is defined both with and without a context…
Error message
The "%s" message is defined both with and without a context, which is not supported because contexts are ignored in message keys.
What it means
PoFileLoader ignores message contexts in keys (msgctxt). If the same msgid appears once without a context and once with one (or with two different contexts), the loader cannot represent both entries and throws InvalidResourceException to avoid silently dropping translations.
Solutions
- Search the .po for the reported msgid and make context usage consistent: give every occurrence the same msgctxt or remove msgctxt from all.
- Deduplicate entries with `msguniq messages.po -o messages.po`.
- If contexts are genuinely needed, split messages into different domains/files.
- Re-export the catalogue from the translation tool ensuring each msgid appears once per context.
Example fix
// before (messages.po) msgid "Save" msgstr "Speichern" msgctxt "menu" msgid "Save" msgstr "Speichern" // after msgctxt "menu" msgid "Save" msgstr "Speichern" // single, consistently-contextualized entry
Defensive patterns
Strategy: validation
Validate before calling
$ids = [];
foreach (explode('\nmsg', file_get_contents($poFile)) as $block) {
if (preg_match('/^id "((?:[^"\\]|\\.)*)"/m', $block, $m)) {
$ctx = preg_match('/^ctxt /m', $block) ? 'with-context' : 'no-context';
$key = $m[1];
if (isset($ids[$key]) && $ids[$key] !== $ctx) {
throw new \RuntimeException(sprintf('PO entry %s mixes context usage', $key));
}
$ids[$key] = $ctx;
}
} Try / catch
try {
$catalogue = $loader->load($poFile, $locale);
} catch (InvalidResourceException $e) {
error_log('PO context conflict: '.$e->getMessage());
$catalogue = new MessageCatalogue($locale);
} Prevention
- Run msguniq on .po files after merges to remove duplicate msgids
- Enforce one msgctxt per msgid in your translation workflow/lint rules
- Resolve merge conflicts in .po files by re-exporting from the translation tool
- Document that contexts are unsupported in message keys and keep usage consistent
When it happens
Trigger: addMessage() (via saveItem) when parsing a .po file containing duplicate msgid entries where one has msgctxt and the other does not, or two entries share a msgid but have different msgctxt values.
Common situations: Hand-merged .po files, translation tools exporting the same string with and without context, merge conflicts resolved incorrectly in catalogue files, copy-pasting entries into a .po.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- MO stream content has an invalid format.
- The Translator does not support the following options
- The file dumper needs a path option.
- Unable to create directory
- No support implemented for dumping XLIFF version
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/adb47f8ef0532462.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/PoFileLoader.php:181
$id = stripcslashes($item['ids']['singular']);
if (isset($item['ids']['plural'])) {
$id .= '|'.stripcslashes($item['ids']['plural']);
}
$translated = (array) $item['translated'];
// PO are by definition indexed so sort by index.
ksort($translated);
// Make sure every index is filled.
end($translated);
$count = key($translated);
// Fill missing spots with '-'.
$empties = array_fill(0, $count + 1, '-');
$translated += $empties;
ksort($translated);
$context = null !== $item['context'] ? stripcslashes($item['context']) : null;
if (\array_key_exists($id, $this->contexts) && $context !== $this->contexts[$id]) {
throw new InvalidResourceException(null === $context || null === $this->contexts[$id]
? \sprintf('The "%s" message is defined both with and without a context, which is not supported because contexts are ignored in message keys.', $id)
: \sprintf('The "%s" message is defined twice with different contexts ("%s" and "%s"), which is not supported because contexts are ignored in message keys.', $id, $this->contexts[$id], $context));
}
$this->contexts[$id] = $context;
$messages[$id] = stripcslashes(implode('|', $translated));
if (null !== $context) {
$this->metadata[$id] = ['context' => $context];
}
}
}
}
View on GitHub (pinned to ae9e8a51bc)