Humanizr/Humanizer · error · InvalidOperationException

'{path}' must use the explicit inventory, reason, sources, a

Error message

'{path}' must use the explicit inventory, reason, sources, and provenance contract in a release locale.

What it means

Thrown by ValidateReleaseCompleteness (the single-catalog variant) when a DurationCaseCatalog has empty Sources. This is the per-catalog check used in tests and targeted validation. It enforces the same provenance contract as the batch check (error 48) but for one catalog at a time.

Source

Thrown at src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs:195

            var unsupportedPaths = unsupportedPathBuilder
                .OrderBy(static path => path, StringComparer.Ordinal)
                .ToArray();
            if (unsupportedPaths.Length > 0)
            {
                throw new InvalidOperationException(
                    $"Release duration-case completeness requires zero unsupported dispositions; found {unsupportedPaths.Length}: {string.Join(", ", unsupportedPaths)}.");
            }

            return new DurationCaseCoverageInput(immutableCatalogs, rows.MoveToImmutable());
        }

        internal static void ValidateReleaseCompleteness(DurationCaseCatalog catalog)
        {
            var path = $"{catalog.LocaleCode}.durationCases";
            if (catalog.Sources.IsEmpty)
            {
                throw new InvalidOperationException(
                    $"'{path}' must use the explicit inventory, reason, sources, and provenance contract in a release locale.");
            }

            var unsupportedPaths = GetUnsupportedPaths(catalog);
            if (unsupportedPaths.Length > 0)
            {
                throw new InvalidOperationException(
                    $"Release duration-case completeness requires zero unsupported dispositions; found {unsupportedPaths.Length}: {string.Join(", ", unsupportedPaths)}.");
            }
        }

        static ImmutableArray<string> GetUnsupportedPaths(DurationCaseCatalog catalog)
        {
            var paths = ImmutableArray.CreateBuilder<string>();
            var path = $"{catalog.LocaleCode}.durationCases";
            if (catalog.Classification == DurationCaseClassification.Unsupported)
            {
                paths.Add($"{path}.classification");

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Parse the locale via the explicit path (ParseExplicit) which requires sources, rather than ParseLegacyForTests.
  2. Ensure the durationCases YAML has a 'sources' key with at least one source entry.
  3. In tests, only call ValidateReleaseCompleteness on catalogs built through the explicit provenance path.

Example fix

// before (test using legacy parse then release validation)
var catalog = DurationCaseNormalization.ParseLegacyForTests("xx", value);
DurationCaseCoverageInput.ValidateReleaseCompleteness(catalog);
// after (test using explicit parse with sources)
var catalog = DurationCaseNormalization.ParseForTests("xx", explicitYamlWithSources);
DurationCaseCoverageInput.ValidateReleaseCompleteness(catalog);
Defensive patterns

Strategy: validation

Validate before calling

// Single-catalog pre-check for sources before calling ValidateReleaseCompleteness
static bool CatalogHasSources(DurationCaseCatalog catalog) => !catalog.Sources.IsEmpty;

Try / catch

// In tests, guard the release check
if (!catalog.Sources.IsEmpty)
{
    DurationCaseCoverageInput.ValidateReleaseCompleteness(catalog);
}

Prevention

When it happens

Trigger: ValidateReleaseCompleteness checks catalog.Sources.IsEmpty and throws if true. Called from tests via HumanizerSourceGenerator.DurationCaseCoverageInput.ValidateReleaseCompleteness(catalog) to verify individual locale catalogs meet release standards.

Common situations: A test constructs a DurationCaseCatalog via the legacy parse path (ParseLegacyForTests) and then passes it to ValidateReleaseCompleteness. The legacy path produces empty sources, so the validation fails. Also used to check a specific locale before the full release build.

Related errors


AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13). Data as JSON: /api/errors/0b66349dc102dfcb. Report an issue: GitHub.