{"record":{"id":"9bbd194e3745da6f","repo":"Humanizr/Humanizer","slug":"a-property-path-is-required","errorCode":null,"errorMessage":"A property path is required.","messagePattern":"A property path is required\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/EngineContractUtilities.cs","lineNumber":49,"sourceCode":"        }\n\n        public static bool TryGetOptionalString(JsonElement root, string? sourcePath, out string? value)\n        {\n            if (TryGetElement(root, sourcePath, out var property) && property.ValueKind == JsonValueKind.String)\n            {\n                value = property.GetString();\n                return true;\n            }\n\n            value = null;\n            return false;\n        }\n\n        public static string GetLeafPropertyName(string? sourcePath)\n        {\n            if (string.IsNullOrWhiteSpace(sourcePath))\n            {\n                throw new InvalidOperationException(\"A property path is required.\");\n            }\n\n            var path = sourcePath!;\n            var lastSeparator = path.LastIndexOf('.');\n            return lastSeparator >= 0 ? path.Substring(lastSeparator + 1) : path;\n        }\n    }\n}","sourceCodeStart":31,"sourceCodeEnd":57,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/EngineContractUtilities.cs#L31-L57","documentation":"EngineContractUtilities.GetLeafPropertyName (EngineContractUtilities.cs:45-55) extracts the last segment of a dot-path and throws when the path is null/empty/whitespace. This is a contract-authoring error: a member that needs a generated property name was given no sourcePath to derive it from.","triggerScenarios":"An engine-contract member has an empty or null sourcePath but the generator still needs to compute a leaf property name from it.","commonSituations":"Refactoring a contract member to inline data while leaving sourcePath empty; copying a member and deleting its sourcePath without adjusting how its name is derived.","solutions":["Provide a concrete non-empty sourcePath for the member.","If the member no longer needs a source-derived name, refactor the contract so GetLeafPropertyName is not called for it."],"exampleFix":"// before\n{ \"sourcePath\": \"\" }\n// after\n{ \"sourcePath\": \"numbers.unitsMap\" }","handlingStrategy":"validation","validationCode":"// Ensure a non-empty sourcePath when a leaf name is needed (C#)\nif (string.IsNullOrWhiteSpace(member.SourcePath))\n    throw new InvalidOperationException(\"Contract member requires a non-empty sourcePath to derive a property name\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never leave sourcePath empty on a contract member that needs a generated name.","When refactoring a member to inline data, remove the leaf-name derivation too.","Lint contract JSON for empty sourcePath values."],"tags":["source-generator","build-time","engine-contract","json","configuration"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}