Humanizr/Humanizer · error · InvalidOperationException

'{path}' must not be empty.

Error message

'{path}' must not be empty.

What it means

Thrown by RequireReason when a reason string (for notApplicable or unsupported realizations) is null, empty, or whitespace-only. The generator requires a human-readable explanation whenever a case or unit is marked as not applicable or unsupported.

Source

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

        static void ValidateProvenance(
            ImmutableArray<string> provenance,
            ImmutableDictionary<string, DurationCaseSource> sources,
            string path)
        {
            foreach (var sourceId in provenance.Where(sourceId => !sources.ContainsKey(sourceId)))
            {
                throw new InvalidOperationException(
                    $"'{path}.provenance' references unknown source '{sourceId}'.");
            }
        }

        static string RequireScalar(SimpleYamlMapping mapping, string key, string path) =>
            mapping.GetScalar(key)
            ?? throw new InvalidOperationException($"'{path}' must define scalar '{key}'.");

        static string RequireReason(string reason, string path) =>
            string.IsNullOrWhiteSpace(reason)
                ? throw new InvalidOperationException($"'{path}' must not be empty.")
                : reason;

        static ImmutableDictionary<string, DurationCaseRealization> EmptyRealizations() =>
            ImmutableDictionary<string, DurationCaseRealization>.Empty.WithComparers(StringComparer.Ordinal);

        static DurationCaseOverlay CreateBaseDurationOverlay()
        {
            var units = ImmutableDictionary.CreateBuilder<string, DurationCaseUnit>(StringComparer.Ordinal);
            foreach (var unit in TimeUnits)
            {
                units[unit] = new DurationCaseUnit(DurationCaseUnitKind.SameAsNominative, null);
            }

            return new DurationCaseOverlay(units.ToImmutable());
        }

        static ImmutableDictionary<string, DurationCaseUnitRealization> EmptyUnitRealizations() =>
            ImmutableDictionary<string, DurationCaseUnitRealization>.Empty.WithComparers(StringComparer.Ordinal);

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Provide a concise, non-empty explanation string for the notApplicable or unsupported key at the reported path.
  2. Rebuild to confirm the reason passes the whitespace check.

Example fix

# before
genitive:
  notApplicable: ""
# after
genitive:
  notApplicable: "Language has no distinct genitive form for durations"
Defensive patterns

Strategy: validation

Validate before calling

# Verify notApplicable and unsupported reasons are non-empty
# python: for case_name, real in realizations.items():
#     for key in ('notApplicable','unsupported'):
#         if key in real: assert real[key] and real[key].strip(), f'empty {key} reason'

Prevention

When it happens

Trigger: A realization uses notApplicable or unsupported with an empty string, a whitespace-only string, or (via the unsupported fallback) a null scalar value.

Common situations: A contributor writes 'notApplicable:' with no value, or 'notApplicable: ""' as a placeholder. The generator mandates a descriptive reason so future maintainers understand why the case/unit is excluded.

Related errors


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