Humanizr/Humanizer · error · InvalidOperationException

Locale '{localeCode}.{path}' must omit the block instead of

Error message

Locale '{localeCode}.{path}' must omit the block instead of declaring engine: 'default'.

What it means

Thrown during canonical locale YAML parsing when a surface block explicitly declares 'engine: default'. The canonical authoring schema forbids redundant default-engine declarations — a block that would resolve to the default engine should be omitted entirely so the fallback is implicit. Only four whitelisted paths (surfaces.ordinal.numeric, surfaces.ordinal.date, surfaces.ordinal.dateOnly, surfaces.clock) are allowed to keep engine: 'default'.

Source

Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:548

            "surfaces.ordinal.numeric",
            "surfaces.ordinal.date",
            "surfaces.ordinal.dateOnly",
            "surfaces.clock"
        ];

        static void RejectExplicitDefaultEngines(string localeCode, string path, SimpleYamlValue value)
        {
            switch (value)
            {
                case SimpleYamlMapping mapping:
                    if (string.Equals(mapping.GetScalar("engine"), "default", StringComparison.Ordinal))
                    {
                        if (ExplicitDefaultEnginePaths.Contains(path))
                        {
                            return;
                        }

                        throw new InvalidOperationException(
                            $"Locale '{localeCode}.{path}' must omit the block instead of declaring engine: 'default'.");
                    }

                    foreach (var entry in mapping.Values)
                    {
                        RejectExplicitDefaultEngines(localeCode, $"{path}.{entry.Key}", entry.Value);
                    }

                    break;

                case SimpleYamlSequence sequence:
                    for (var index = 0; index < sequence.Items.Length; index++)
                    {
                        RejectExplicitDefaultEngines(localeCode, $"{path}[{index}]", sequence.Items[index]);
                    }

                    break;
                default:

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Remove the entire surface block (e.g. delete the 'list:' key and its children) so the default engine is implied by absence.
  2. If the surface genuinely needs the default engine and the path is ordinal.numeric, ordinal.date, ordinal.dateOnly, or clock, verify the path string matches exactly — those four are whitelisted.
  3. If you need a non-default engine, set engine to the actual engine name (e.g. 'oxford', 'conjunction', 'delimited') instead of 'default'.

Example fix

# before
surfaces:
  list:
    engine: default
# after (omit the block entirely)
surfaces: {}
Defensive patterns

Strategy: validation

Validate before calling

// Before authoring a locale YAML, scan surfaces for engine: 'default'
static bool HasForbiddenDefaultEngine(SimpleYamlMapping surfaces, string localeCode)
{
    var whitelisted = new HashSet<string>
    {
        "surfaces.ordinal.numeric", "surfaces.ordinal.date",
        "surfaces.ordinal.dateOnly", "surfaces.clock"
    };
    return Scan(surfaces, "surfaces");

    bool Scan(SimpleYamlValue node, string path) => node switch
    {
        SimpleYamlMapping m => (m.GetScalar("engine") == "default" && !whitelisted.Contains(path))
            || m.Values.Any(e => Scan(e.Value, $"{path}.{e.Key}")),
        SimpleYamlSequence s => s.Items.Select((item, i) => Scan(item, $"{path}[{i}]")).Any(b => b),
        _ => false
    };
}

Prevention

When it happens

Trigger: CanonicalLocaleAuthoring.Parse walks every locale YAML surface and calls RejectExplicitDefaultEngines recursively. Any mapping anywhere in the surfaces tree whose 'engine' scalar equals 'default' (and whose path is not in ExplicitDefaultEnginePaths) triggers this. For example, writing 'surfaces:\n list:\n engine: default' in a checked-in locale file.

Common situations: A contributor copies a surface block from another locale, sees engine: 'default' documented somewhere, and pastes it verbatim. Or a migration tool emits engine: 'default' for surfaces that should just be absent. Occurs when upgrading from an older locale schema that permitted explicit defaults.

Related errors


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