Humanizr/Humanizer · error · InvalidOperationException

'{path}' must define provenance.

Error message

'{path}' must define provenance.

What it means

Thrown by ParseProvenance when required is true and the mapping does not contain a 'provenance' key at all. Phrase, sameRenderedAs, and notApplicable realizations all require provenance (a citation chain); only the unsupported fallback makes it optional.

Source

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

            _ = resolving.Remove(node);
            if (aliasing && result.Kind is DurationCaseUnitKind.NotApplicable or DurationCaseUnitKind.Unsupported)
            {
                throw new InvalidOperationException(
                    $"'{path}' aliases '{node}' to a case or unit that is not applicable or unsupported.");
            }

            return result;
        }

        static ImmutableArray<string> ParseProvenance(
            SimpleYamlMapping mapping,
            string path,
            bool required)
        {
            if (!mapping.TryGetValue("provenance", out var value))
            {
                return required
                    ? throw new InvalidOperationException($"'{path}' must define provenance.")
                    : [];
            }

            if (value is not SimpleYamlSequence sequence)
            {
                throw new InvalidOperationException($"'{path}.provenance' must be a sequence.");
            }

            var result = ImmutableArray.CreateBuilder<string>(sequence.Items.Length);
            var seen = new HashSet<string>(StringComparer.Ordinal);
            foreach (var item in sequence.Items)
            {
                if (item is not SimpleYamlScalar scalar || string.IsNullOrWhiteSpace(scalar.Value))
                {
                    throw new InvalidOperationException(
                        $"'{path}.provenance' must contain non-empty source identifiers.");
                }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Add a 'provenance' key to the unit realization mapping at the reported path.
  2. Set it to a YAML sequence of source IDs that are defined in the locale's 'sources' section.
  3. Rebuild to confirm provenance is accepted.

Example fix

# before
second:
  phrase:
    single: jedna sekunda
    multiple:
      forms:
        default: sekund
# after
second:
  phrase:
    single: jedna sekunda
    multiple:
      forms:
        default: sekund
  provenance: [cldr-42]
Defensive patterns

Strategy: validation

Validate before calling

# Verify provenance exists for phrase/sameRenderedAs/notApplicable realizations
# python: for unit in realization_units:
#     disc = [k for k in ('phrase','sameRenderedAs','notApplicable') if k in unit]
#     if disc: assert 'provenance' in unit, 'missing provenance'

Prevention

When it happens

Trigger: A unit realization with a phrase, sameRenderedAs, or notApplicable discriminator is missing the 'provenance' key, so TryGetValue('provenance', ...) returns false and the required branch throws.

Common situations: A contributor authors a new duration-case realization but forgets to cite the source data. The generator enforces provenance for all renderable or aliased realizations to ensure traceability of linguistic data.

Related errors


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