{"record":{"id":"adb47f8ef0532462","repo":"symfony/translation","slug":"the-s-message-is-defined-both-with-and-without-a-context","errorCode":null,"errorMessage":"The \"%s\" message is defined both with and without a context, which is not supported because contexts are ignored in message keys.","messagePattern":"The \"(.+?)\" message is defined both with and without a context, which is not supported because contexts are ignored in message keys\\.","errorType":"exception","errorClass":"InvalidResourceException","httpStatus":null,"severity":"error","filePath":"Loader/PoFileLoader.php","lineNumber":181,"sourceCode":"            $id = stripcslashes($item['ids']['singular']);\n            if (isset($item['ids']['plural'])) {\n                $id .= '|'.stripcslashes($item['ids']['plural']);\n            }\n\n            $translated = (array) $item['translated'];\n            // PO are by definition indexed so sort by index.\n            ksort($translated);\n            // Make sure every index is filled.\n            end($translated);\n            $count = key($translated);\n            // Fill missing spots with '-'.\n            $empties = array_fill(0, $count + 1, '-');\n            $translated += $empties;\n            ksort($translated);\n\n            $context = null !== $item['context'] ? stripcslashes($item['context']) : null;\n            if (\\array_key_exists($id, $this->contexts) && $context !== $this->contexts[$id]) {\n                throw new InvalidResourceException(null === $context || null === $this->contexts[$id]\n                    ? \\sprintf('The \"%s\" message is defined both with and without a context, which is not supported because contexts are ignored in message keys.', $id)\n                    : \\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));\n            }\n            $this->contexts[$id] = $context;\n\n            $messages[$id] = stripcslashes(implode('|', $translated));\n\n            if (null !== $context) {\n                $this->metadata[$id] = ['context' => $context];\n            }\n        }\n    }\n}\n","sourceCodeStart":163,"sourceCodeEnd":195,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Loader/PoFileLoader.php#L163-L195","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (messages.po)\nmsgid \"Save\"\nmsgstr \"Speichern\"\n\nmsgctxt \"menu\"\nmsgid \"Save\"\nmsgstr \"Speichern\"\n// after\nmsgctxt \"menu\"\nmsgid \"Save\"\nmsgstr \"Speichern\"  // single, consistently-contextualized entry","handlingStrategy":"validation","validationCode":"$ids = [];\nforeach (explode('\\nmsg', file_get_contents($poFile)) as $block) {\n    if (preg_match('/^id \"((?:[^\"\\\\]|\\\\.)*)\"/m', $block, $m)) {\n        $ctx = preg_match('/^ctxt /m', $block) ? 'with-context' : 'no-context';\n        $key = $m[1];\n        if (isset($ids[$key]) && $ids[$key] !== $ctx) {\n            throw new \\RuntimeException(sprintf('PO entry %s mixes context usage', $key));\n        }\n        $ids[$key] = $ctx;\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $catalogue = $loader->load($poFile, $locale);\n} catch (InvalidResourceException $e) {\n    error_log('PO context conflict: '.$e->getMessage());\n    $catalogue = new MessageCatalogue($locale);\n}","preventionTips":["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"],"tags":["gettext","po","translation","duplicate-key"],"backgroundTag":"conflicting-config-options","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}