Humanizr/Humanizer · error · InvalidOperationException

'{path}' must define scalar '{key}'.

Error message

'{path}' must define scalar '{key}'.

What it means

Thrown by RequireScalar when a mapping does not contain the requested scalar key (GetScalar returns null). This helper is used to fetch mandatory scalar values such as sameRenderedAs targets, notApplicable reasons, or unsupported reasons within various mapping contexts.

Source

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

            return result.MoveToImmutable();
        }

        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());

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Inspect the mapping at the reported path and identify the missing scalar key named in the message.
  2. Add the scalar value (a non-null YAML string) for that key.
  3. Rebuild to confirm the scalar is found.

Example fix

# before — source object missing 'revision'
cldr-42:
  kind: cldr
  url: https://unicode.org/cldr
  locator: common/...
  credit: Unicode
# after
cldr-42:
  kind: cldr
  url: https://unicode.org/cldr
  revision: '42'
  locator: common/...
  credit: Unicode
Defensive patterns

Strategy: validation

Validate before calling

# Verify mandatory scalar fields exist in source objects and realizations
# python: required_fields = ['kind','url','revision','locator','credit']
#         for sid, src in yaml['durationCases']['sources'].items():
#             for f in required_fields: assert f in src, f'missing {f} in source {sid}'

Prevention

When it happens

Trigger: A code path calls RequireScalar for a key that is absent from the mapping. In the duration-case model, this surfaces when an expected scalar value is missing from a realization or source mapping.

Common situations: A contributor uses a discriminator key that the parser accepts as present but then the downstream RequireScalar call for a companion field finds nothing. Also occurs when editing source objects that omit a mandatory scalar field (kind, url, revision, locator, credit).

Related errors


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