Humanizr/Humanizer · error · InvalidOperationException
Locale '{locale.LocaleCode}' has no authored or same-languag
Error message
Locale '{locale.LocaleCode}' has no authored or same-language inherited durationCases classification. What it means
Thrown by DurationCaseCoverageInput.Create when building the coverage row for a locale that neither authors 'durationCases' in its own file (AuthoredFeatureNames doesn't contain it) nor has a variantOf parent (VariantOf is null). The coverage table needs to label each locale as authored or same-language-inherited, and a root locale with no authored durationCases and no parent has no valid label.
Source
Thrown at src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs:155
var catalog = DurationCaseNormalization.Parse(
locale.LocaleCode,
value,
GetExplicitDurationCaseNumberDetector(locale),
phrases);
catalogs.Add(catalog);
rows.Add(new DurationCaseCoverageRow(
locale.LocaleCode,
locale.AuthoredFeatureNames.Contains("durationCases")
? catalog.Classification switch
{
DurationCaseClassification.Distinct => "distinct",
DurationCaseClassification.Invariant => "invariant",
DurationCaseClassification.NotApplicable => "not-applicable",
_ => "unsupported"
}
: locale.VariantOf is not null
? "same-language-inherited"
: throw new InvalidOperationException(
$"Locale '{locale.LocaleCode}' has no authored or same-language inherited durationCases classification."),
locale.VariantOf));
}
var immutableCatalogs = catalogs.MoveToImmutable();
var legacyCatalogs = immutableCatalogs
.Where(static catalog => catalog.Sources.IsEmpty)
.Select(static catalog => catalog.LocaleCode)
.OrderBy(static locale => locale, StringComparer.Ordinal)
.ToArray();
if (legacyCatalogs.Length > 0)
{
throw new InvalidOperationException(
$"Release duration-case locales must use the explicit inventory, reason, sources, and provenance contract: {string.Join(", ", legacyCatalogs)}.");
}
var unsupportedPathBuilder = ImmutableArray.CreateBuilder<string>();
foreach (var catalog in immutableCatalogs)View on GitHub (pinned to ffc2b77c0f)
Solutions
- Author the durationCases surface directly in the locale's YAML file so AuthoredFeatureNames includes 'durationCases'.
- If the locale is genuinely a variant, add a 'variantOf' property pointing to its parent locale.
- Ensure the locale catalog resolution correctly tags authored features for locales that define durationCases in their own file.
Example fix
# before (root locale with no authored durationCases and no variantOf)
locale: en
surfaces:
list:
engine: oxford
# after (author durationCases directly)
locale: en
surfaces:
durationCases:
classification: not-applicable
reason: "English has no grammatical case for durations."
sources: [...]
provenance: { ... } Defensive patterns
Strategy: validation
Validate before calling
// Ensure root locales either author durationCases or declare variantOf
static bool LocalesHaveClassificationSource(LocaleCatalogInput catalog) =>
catalog.Locales.All(locale =>
locale.AuthoredFeatureNames.Contains("durationCases") || locale.VariantOf is not null); Prevention
- Root/base locales must author durationCases directly in their YAML file.
- Variant locales must declare 'variantOf' pointing to a parent that has durationCases.
- Never rely on implicit/default resolution for durationCases in release builds.
When it happens
Trigger: In the coverage-row construction, the ternary checks AuthoredFeatureNames.Contains('durationCases') first, then VariantOf is not null. If both fail, the throw expression fires. This means the locale resolved durationCases from somewhere (error 46 didn't fire) but didn't author it and has no parent — an inconsistent state.
Common situations: A root/base locale (e.g. 'en') that inherits durationCases from a default/fallback mechanism rather than authoring it or declaring variantOf. This can happen if the locale resolution pipeline injects a default durationCases without marking the locale as authored or variant.
Related errors
- Locale '{locale.LocaleCode}' must classify the durationCases
- Release duration-case locales must use the explicit inventor
- Release duration-case completeness requires zero unsupported
- '{path}' must use the explicit inventory, reason, sources, a
- '{path}' must define exactly one of phrase, sameRenderedAs,
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/cf3560030bec27c5.
Report an issue: GitHub.