Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.{path}' must be a sequence or sparse nu
Error message
Locale '{localeCode}.{path}' must be a sequence or sparse numeric mapping. What it means
minuteWordsMap must be either a sequence (dense) or a numeric-keyed mapping (sparse); any other shape, e.g. a bare scalar, is rejected (CanonicalLocaleAuthoring.cs:268-274).
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:272
static SimpleYamlMapping NormalizeClockSurface(string localeCode, SimpleYamlMapping clockSurface)
{
if (clockSurface.DuplicateKeys.Contains("minuteWordsMap"))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.clock.minuteWordsMap' defines duplicate entries; choose either the dense or sparse form.");
}
if (!clockSurface.TryGetValue("minuteWordsMap", out var minuteWordsMap))
{
return clockSurface;
}
const string path = "surfaces.clock.minuteWordsMap";
SimpleYamlValue normalizedMinuteWordsMap = minuteWordsMap switch
{
SimpleYamlSequence sequence => NormalizeMinuteWordsSequence(localeCode, path, sequence),
SimpleYamlMapping mapping => NormalizeMinuteWordsMapping(localeCode, path, mapping),
_ => throw new InvalidOperationException(
$"Locale '{localeCode}.{path}' must be a sequence or sparse numeric mapping.")
};
var normalizedClockSurface = clockSurface.Values.ToBuilder();
normalizedClockSurface["minuteWordsMap"] = normalizedMinuteWordsMap;
return new SimpleYamlMapping(normalizedClockSurface.ToImmutable());
}
static SimpleYamlMapping NormalizeMinuteWordsSequence(
string localeCode,
string path,
SimpleYamlSequence sequence)
{
if (sequence.Items.Length > 60)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.{path}' must contain at most 60 entries for minute slots 0 through 59.");
}View on GitHub (pinned to ffc2b77c0f)
Solutions
- Use the sequence form for a full 0-59 list, or a mapping keyed by integer minutes for sparse overrides.
- For a single override use `minuteWordsMap:` then `15: "a quarter"`.
- Rebuild.
Example fix
# before
surfaces:
clock:
minuteWordsMap: "quarter"
# after
surfaces:
clock:
minuteWordsMap:
15: "a quarter" Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
m = ((doc.get('surfaces') or {}).get('clock') or {}).get('minuteWordsMap')
if m is not None:
assert isinstance(m, (list, dict)), 'minuteWordsMap must be a sequence or sparse mapping' Prevention
- 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.
When it happens
Trigger: Writing `minuteWordsMap: "quarter"` (scalar) or some unsupported node type.
Common situations: Hand-typing a single override as a scalar instead of a one-key mapping.
Related errors
- Locale '{localeCode}.surfaces.clock.minuteWordsMap' defines
- Locale '{localeCode}.{path}' must contain at most 60 entries
- Locale '{localeCode}.{path}' defines duplicate key '{mapping
- Locale '{localeCode}.{path}' requires integer keys. Invalid
- Locale '{localeCode}.{path}' keys must be between 0 and 59.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/dd65335b97485b4a.
Report an issue: GitHub.