{"record":{"id":"f0dce4bad199d0b6","repo":"Humanizr/Humanizer","slug":"locale-localecode-path-keys-must-be-between","errorCode":null,"errorMessage":"Locale '{localeCode}.{path}' keys must be between 0 and 59. Invalid key '{entry.Key}'.","messagePattern":"Locale '(.+?)\\.(.+?)' keys must be between 0 and 59\\. Invalid key '(.+?)'\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs","lineNumber":324,"sourceCode":"        {\n            if (!mapping.DuplicateKeys.IsDefaultOrEmpty)\n            {\n                throw new InvalidOperationException(\n                    $\"Locale '{localeCode}.{path}' defines duplicate key '{mapping.DuplicateKeys[0]}'.\");\n            }\n\n            var normalizedValues = ImmutableDictionary.CreateBuilder<string, SimpleYamlValue>(StringComparer.Ordinal);\n            foreach (var entry in mapping.Values)\n            {\n                if (!int.TryParse(entry.Key, NumberStyles.Integer, CultureInfo.InvariantCulture, out var minute))\n                {\n                    throw new InvalidOperationException(\n                        $\"Locale '{localeCode}.{path}' requires integer keys. Invalid key '{entry.Key}'.\");\n                }\n\n                if (minute is < 0 or > 59)\n                {\n                    throw new InvalidOperationException(\n                        $\"Locale '{localeCode}.{path}' keys must be between 0 and 59. Invalid key '{entry.Key}'.\");\n                }\n\n                var canonicalKey = minute.ToString(CultureInfo.InvariantCulture);\n                if (normalizedValues.ContainsKey(canonicalKey))\n                {\n                    throw new InvalidOperationException(\n                        $\"Locale '{localeCode}.{path}' defines duplicate numeric minute slot {minute}.\");\n                }\n\n                ValidateMinuteWordValue(localeCode, path, entry.Key, entry.Value, allowEmpty: false);\n                normalizedValues[canonicalKey] = entry.Value;\n            }\n\n            return new SimpleYamlMapping(normalizedValues.ToImmutable());\n        }\n\n        static void ValidateMinuteWordValue(","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs#L306-L342","documentation":"Sparse minuteWordsMap keys must be between 0 and 59 inclusive (CanonicalLocaleAuthoring.cs:322-326). Values outside that range have no clock-minute meaning.","triggerScenarios":"A key like `60:`, `120:`, or `-5:` in the sparse mapping.","commonSituations":"Mis-typing a value; confusing seconds (0-59 is shared with minutes) and adding a 60+ entry.","solutions":["Change the key to a valid minute in 0-59.","Remove the out-of-range entry if it was a mistake.","Rebuild."],"exampleFix":"# before\nsurfaces:\n  clock:\n    minuteWordsMap:\n      60: \"top of the hour\"\n# after\nsurfaces:\n  clock:\n    minuteWordsMap:\n      0: \"top of the hour\"","handlingStrategy":"validation","validationCode":"import yaml, sys\ndoc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))\nm = ((doc.get('surfaces') or {}).get('clock') or {}).get('minuteWordsMap')\nif isinstance(m, dict):\n    for k in m:\n        n = int(k)\n        assert 0 <= n <= 59, f'minuteWordsMap key {k} out of range 0-59'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Author locales against the canonical schema; the error message lists the exact allowed names.","Run `dotnet build src/Humanizer/Humanizer.csproj` locally so the generator reports locale errors before push.","Copy an existing compliant locale file as your template rather than writing YAML from scratch."],"tags":["locale-authoring","yaml","source-generator","build","localization","clock"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}