{"record":{"id":"52c5911153a4c858","repo":"Humanizr/Humanizer","slug":"path-provenance-contains-duplicate-source-sc","errorCode":null,"errorMessage":"'{path}.provenance' contains duplicate source '{scalar.Value}'.","messagePattern":"'(.+?)\\.provenance' contains duplicate source '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs","lineNumber":1064,"sourceCode":"\n            if (value is not SimpleYamlSequence sequence)\n            {\n                throw new InvalidOperationException($\"'{path}.provenance' must be a sequence.\");\n            }\n\n            var result = ImmutableArray.CreateBuilder<string>(sequence.Items.Length);\n            var seen = new HashSet<string>(StringComparer.Ordinal);\n            foreach (var item in sequence.Items)\n            {\n                if (item is not SimpleYamlScalar scalar || string.IsNullOrWhiteSpace(scalar.Value))\n                {\n                    throw new InvalidOperationException(\n                        $\"'{path}.provenance' must contain non-empty source identifiers.\");\n                }\n\n                if (!seen.Add(scalar.Value))\n                {\n                    throw new InvalidOperationException(\n                        $\"'{path}.provenance' contains duplicate source '{scalar.Value}'.\");\n                }\n\n                result.Add(scalar.Value);\n            }\n\n            if (required && result.Count == 0)\n            {\n                throw new InvalidOperationException($\"'{path}.provenance' must not be empty.\");\n            }\n\n            return result.MoveToImmutable();\n        }\n\n        static void ValidateProvenance(\n            ImmutableArray<string> provenance,\n            ImmutableDictionary<string, DurationCaseSource> sources,\n            string path)","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs#L1046-L1082","documentation":"Thrown by ParseProvenance when the same source identifier string appears more than once in the provenance sequence. The parser uses a HashSet to track seen IDs and throws on any duplicate to prevent redundant or erroneous citations.","triggerScenarios":"The provenance list contains the same source ID twice, e.g. [cldr-42, cldr-42].","commonSituations":"A contributor merges two provenance lists or copies entries and accidentally leaves a duplicate source ID. Also occurs when a source is cited under slightly different keys that resolve to the same string.","solutions":["Inspect the provenance list at the reported path and find the duplicated source ID named in the message.","Remove the duplicate so each source ID appears exactly once.","Rebuild to confirm no duplicates remain."],"exampleFix":"# before\nprovenance: [cldr-42, grammar-ref, cldr-42]\n# after\nprovenance: [cldr-42, grammar-ref]","handlingStrategy":"validation","validationCode":"# Verify no duplicate source IDs in provenance\n# python: assert len(unit['provenance']) == len(set(unit['provenance'])), 'duplicate provenance'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When merging provenance lists, deduplicate before writing.","Use a YAML linter or script that checks for duplicate list elements.","Build after editing provenance to catch duplicates at the specific path."],"tags":["humanizer","locale","yaml","source-generator","duration-cases","provenance","build-time"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}