Humanizr/Humanizer · error · InvalidOperationException

'{path}' aliases '{node}' to a case or unit that is not appl

Error message

'{path}' aliases '{node}' to a case or unit that is not applicable or unsupported.

What it means

Thrown by ResolveUnit when aliasing is true (i.e. the resolver is following a sameRenderedAs reference) and the resolved target unit turns out to be NotApplicable or Unsupported. The generator forbids aliasing to non-renderable cases because the aliasing case would inherit a non-result, making it ambiguous.

Source

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

                        unitName,
                        inventory,
                        realizations,
                        resolving,
                        path,
                        aliasing: true);
                    break;
                case DurationCaseRealizationKind.NotApplicable:
                    result = new DurationCaseUnit(DurationCaseUnitKind.NotApplicable, null);
                    break;
                default:
                    result = new DurationCaseUnit(DurationCaseUnitKind.Unsupported, null);
                    break;
            }

            _ = 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.")
                    : [];
            }

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Check the target case/unit referenced by sameRenderedAs at the reported node.
  2. If the target is genuinely notApplicable or unsupported, mark the aliasing case/unit as notApplicable or unsupported directly instead of aliasing.
  3. If the target should have a real phrase, author it as a phrase realization instead of notApplicable/unsupported.
  4. Rebuild to confirm the alias resolves to a renderable unit.

Example fix

# before (accusative aliases genitive, but genitive is notApplicable)
accusative:
  sameRenderedAs: genitive
genitive:
  notApplicable: language has no genitive duration
# after
accusative:
  notApplicable: language has no accusative duration
genitive:
  notApplicable: language has no genitive duration
Defensive patterns

Strategy: validation

Validate before calling

# Verify no sameRenderedAs target resolves to notApplicable or unsupported
# python: for case_name, real in realizations.items():
#     if 'sameRenderedAs' in real:
#         target = realizations[real['sameRenderedAs']]
#         assert 'notApplicable' not in target and 'unsupported' not in target

Prevention

When it happens

Trigger: A case's sameRenderedAs points to another case whose realization (or specific unit realization) is marked notApplicable or unsupported, so the resolved DurationCaseUnitKind is NotApplicable or Unsupported and the aliasing guard fires.

Common situations: A contributor sets up case A to alias case B, but case B is marked notApplicable (e.g. the language has no distinct genitive for durations). The contributor expected case A to inherit B's actual phrase but instead inherits a void. Also occurs when a unit-level sameRenderedAs targets a unit marked unsupported.

Related errors


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