{"record":{"id":"ca71e0b597b7fd0d","repo":"Humanizr/Humanizer","slug":"locale-localecode-path-must-omit-the-block-i","errorCode":null,"errorMessage":"Locale '{localeCode}.{path}' must omit the block instead of declaring engine: 'default'.","messagePattern":"Locale '(.+?)\\.(.+?)' must omit the block instead of declaring engine: 'default'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs","lineNumber":548,"sourceCode":"            \"surfaces.ordinal.numeric\",\n            \"surfaces.ordinal.date\",\n            \"surfaces.ordinal.dateOnly\",\n            \"surfaces.clock\"\n        ];\n\n        static void RejectExplicitDefaultEngines(string localeCode, string path, SimpleYamlValue value)\n        {\n            switch (value)\n            {\n                case SimpleYamlMapping mapping:\n                    if (string.Equals(mapping.GetScalar(\"engine\"), \"default\", StringComparison.Ordinal))\n                    {\n                        if (ExplicitDefaultEnginePaths.Contains(path))\n                        {\n                            return;\n                        }\n\n                        throw new InvalidOperationException(\n                            $\"Locale '{localeCode}.{path}' must omit the block instead of declaring engine: 'default'.\");\n                    }\n\n                    foreach (var entry in mapping.Values)\n                    {\n                        RejectExplicitDefaultEngines(localeCode, $\"{path}.{entry.Key}\", entry.Value);\n                    }\n\n                    break;\n\n                case SimpleYamlSequence sequence:\n                    for (var index = 0; index < sequence.Items.Length; index++)\n                    {\n                        RejectExplicitDefaultEngines(localeCode, $\"{path}[{index}]\", sequence.Items[index]);\n                    }\n\n                    break;\n                default:","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs#L530-L566","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove the entire surface block (e.g. delete the 'list:' key and its children) so the default engine is implied by absence.","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.","If you need a non-default engine, set engine to the actual engine name (e.g. 'oxford', 'conjunction', 'delimited') instead of 'default'."],"exampleFix":"# before\nsurfaces:\n  list:\n    engine: default\n# after (omit the block entirely)\nsurfaces: {}","handlingStrategy":"validation","validationCode":"// Before authoring a locale YAML, scan surfaces for engine: 'default'\nstatic bool HasForbiddenDefaultEngine(SimpleYamlMapping surfaces, string localeCode)\n{\n    var whitelisted = new HashSet<string>\n    {\n        \"surfaces.ordinal.numeric\", \"surfaces.ordinal.date\",\n        \"surfaces.ordinal.dateOnly\", \"surfaces.clock\"\n    };\n    return Scan(surfaces, \"surfaces\");\n\n    bool Scan(SimpleYamlValue node, string path) => node switch\n    {\n        SimpleYamlMapping m => (m.GetScalar(\"engine\") == \"default\" && !whitelisted.Contains(path))\n            || m.Values.Any(e => Scan(e.Value, $\"{path}.{e.Key}\")),\n        SimpleYamlSequence s => s.Items.Select((item, i) => Scan(item, $\"{path}[{i}]\")).Any(b => b),\n        _ => false\n    };\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Author locale YAML by duplicating a known-good locale file and editing values, not by writing from scratch.","Never write 'engine: default' — omit the surface block entirely when the default is desired.","Run CanonicalLocaleAuthoring.Parse on the locale file in a unit test before committing."],"tags":["source-generator","locale","yaml","canonical-authoring","engine"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}