{"record":{"id":"b028a45aa5fd90eb","repo":"Humanizr/Humanizer","slug":"duplicate-inflection-lexeme-id-id","errorCode":null,"errorMessage":"Duplicate inflection lexeme id '{id}'.","messagePattern":"Duplicate inflection lexeme id '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/InflectionCatalogParsing.cs","lineNumber":257,"sourceCode":"            }\n\n            var ids = new HashSet<string>(StringComparer.Ordinal);\n            var lexemes = ImmutableArray.CreateBuilder<InflectionLexemeInput>();\n            foreach (var value in lexemeSequence.Items)\n            {\n                if (value is not SimpleYamlMapping lexeme)\n                {\n                    throw new InvalidOperationException(\"Inflection lexemes must be mappings.\");\n                }\n\n                ValidateProperties(\n                    lexeme,\n                    \"Inflection lexeme\",\n                    \"id\", \"pos\", \"countability\", \"sense\", \"forms\", \"sources\");\n                var id = GetRequiredScalar(lexeme, \"id\", \"Inflection lexeme must define id\");\n                if (!ids.Add(id))\n                {\n                    throw new InvalidOperationException($\"Duplicate inflection lexeme id '{id}'.\");\n                }\n\n                if (GetRequiredScalar(lexeme, \"pos\", $\"Inflection lexeme '{id}' must define pos\") != \"noun\")\n                {\n                    throw new InvalidOperationException($\"Inflection lexeme '{id}' pos must be 'noun'.\");\n                }\n\n                var countability = GetRequiredScalar(\n                    lexeme,\n                    \"countability\",\n                    $\"Inflection lexeme '{id}' must define countability\");\n                if (!Countabilities.Contains(countability))\n                {\n                    throw new InvalidOperationException(\n                        $\"Inflection lexeme '{id}' countability '{countability}' is unsupported.\");\n                }\n\n                string? sense = null;","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/InflectionCatalogParsing.cs#L239-L275","documentation":"Lexeme ids must be unique within a locale (ordinal string comparison). ParseLexemes tracks ids in a HashSet and throws when 'ids.Add(id)' returns false, because the inflection catalog keys lexemes by id.","triggerScenarios":"Two entries under 'lexemes:' share the same 'id:' value (exact or case-differing).","commonSituations":"Copy-pasting a lexeme block to add a sense variant and forgetting to rename the id; case collisions from a casing-mode change.","solutions":["Give each lexeme a distinct id (e.g. suffix by sense or part of speech)"],"exampleFix":"# before\n      - id: 'zz.noun.cat'\n        ...\n      - id: 'zz.noun.cat'\n        sense: 'animal'\n# after\n      - id: 'zz.noun.cat'\n        ...\n      - id: 'zz.noun.cat.animal'\n        sense: 'animal'","handlingStrategy":"validation","validationCode":"var ids = new HashSet<string>(StringComparer.Ordinal);\nforeach (var lexeme in lexemes)\n    if (!ids.Add(lexeme.Id))\n        Report($\"{locale}: duplicate lexeme id '{lexeme.Id}'.\");","typeGuard":"static bool LexemeIdsUnique(IEnumerable<Lexeme> lexemes) =>\n    lexemes.Select(l => l.Id).Distinct(StringComparer.Ordinal).Count() == lexemes.Count();","tryCatchPattern":null,"preventionTips":["Encode part-of-speech and sense into the id to avoid collisions","Re-run the build after duplicating a lexeme block"],"tags":["inflection","localization","yaml","source-generator","locale","validation"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}