{"record":{"id":"1d22838254668c71","repo":"Humanizr/Humanizer","slug":"enum-members-require-an-enum-type","errorCode":null,"errorMessage":"Enum members require an enum type.","messagePattern":"Enum members require an enum type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/NumberToWordsEngineContractFactory.cs","lineNumber":444,"sourceCode":"        static string CreateObjectValue(JsonElement root, EngineContractMember member, bool useCultureParameter)\n        {\n            var objectRoot = string.IsNullOrWhiteSpace(member.SourcePath)\n                ? root\n                : EngineContractUtilities.GetRequiredElement(root, member.SourcePath);\n\n            // Nested profile objects let the YAML stay grouped by meaning while the generated code\n            // still calls an explicit runtime constructor shape. This keeps the authoring surface\n            // readable without paying any runtime mapping cost.\n            return member.TypeName is null\n                ? \"new(\" + CreateConstructorValues(objectRoot, member.Members, useCultureParameter) + \")\"\n                : \"new \" + member.TypeName + \"(\" + CreateConstructorValues(objectRoot, member.Members, useCultureParameter) + \")\";\n        }\n\n        static string CreateEnumValue(JsonElement root, EngineContractMember member)\n        {\n            if (member.EnumType is null)\n            {\n                throw new InvalidOperationException(\"Enum members require an enum type.\");\n            }\n\n            return member.EnumType + \".\" + ToEnumMemberName(GetStringValue(root, member));\n        }\n\n        static string CreateNullableIntStringDictionaryValue(JsonElement root, EngineContractMember member)\n        {\n            if (EngineContractUtilities.TryGetElement(root, member.SourcePath, out _))\n            {\n                return CreateNullableIntStringFrozenDictionaryExpression(root, EngineContractUtilities.GetLeafPropertyName(member.SourcePath));\n            }\n\n            return member.MissingValue switch\n            {\n                \"empty\" => \"FrozenDictionary<int, string>.Empty\",\n                _ => \"null\"\n            };\n        }","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/NumberToWordsEngineContractFactory.cs#L426-L462","documentation":"A contract member with kind 'enum' must specify an EnumType (the C# enum type name) so the factory can emit a fully qualified enum member access. CreateEnumValue checks for null EnumType and throws because it cannot construct 'null.Value' — the enum type name is load-bearing for code generation.","triggerScenarios":"An EngineContractMember is constructed with kind='enum' but enumType=null. CreateEnumValue at line 442 throws. This is a generator-level contract definition bug, not a locale YAML problem.","commonSituations":"Defining a new contract member for an enum-backed property and forgetting to set the EnumType parameter. Refactoring a member from string to enum without adding the enum type name. A positional argument mismatch in the constructor call shifting values.","solutions":["Set the enumType parameter on the EngineContractMember to the fully qualified C# enum type name (e.g., 'BillionStrategy').","If the member should not be an enum, change its kind to 'string' or another appropriate kind.","Verify the positional argument order in the EngineContractMember constructor matches the parameter list."],"exampleFix":"// before\nnew EngineContractMember(\n    kind: \"enum\",\n    sourcePath: \"billionStrategy\",\n    enumType: null,\n    ...)\n// after\nnew EngineContractMember(\n    kind: \"enum\",\n    sourcePath: \"billionStrategy\",\n    enumType: \"BillionStrategy\",\n    ...)","handlingStrategy":"validation","validationCode":"// Validate enum members have a type before generation:\nforeach (var m in contract.Members)\n    if (m.Kind == \"enum\" && string.IsNullOrEmpty(m.EnumType))\n        throw new ArgumentException(\"Enum member requires EnumType.\");","typeGuard":"static bool IsEnumMemberValid(EngineContractMember m) =>\n    m.Kind != \"enum\" || !string.IsNullOrEmpty(m.EnumType);","tryCatchPattern":null,"preventionTips":["When defining an enum-typed contract member, always set the enumType parameter.","Add a contract validation pass in EngineContractCatalog that checks all enum members have types.","Use named arguments in the EngineContractMember constructor to avoid positional argument confusion."],"tags":["source-generator","number-to-words","contract","enum","engine-contract","build-time"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}