Humanizr/Humanizer · error · InvalidOperationException
Unsupported clock-notation contract member kind '{member.Kin
Error message
Unsupported clock-notation contract member kind '{member.Kind}'. What it means
Thrown during source generation by CreateMemberValue when binding a clock-notation engine contract member whose Kind is not one of the supported values: 'profile-object', 'string', 'enum', 'bool', 'int32', or 'optional-string-array'. The switch's default arm fires for any unrecognized member kind, indicating a mismatch between the engine contract definition and the generator's supported member types.
Source
Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/TimeOnlyToClockNotationEngineContractFactory.cs:54
/// everything in an unnecessary extra tuple constructor.
/// </summary>
static string CreateConstructorValues(JsonElement root, ImmutableArray<EngineContractMember> members) =>
members.Length == 1 && members[0].Kind == "profile-object"
? CreateMemberValue(root, members[0])
: "new(" + string.Join(", ", members.Select(member => CreateMemberValue(root, member))) + ")";
static string CreateMemberValue(JsonElement root, EngineContractMember member) =>
member.Kind switch
{
"profile-object" => CreateObjectValue(root, member),
"string" => QuoteLiteral(GetStringValue(root, member)),
"enum" => CreateEnumValue(root, member),
"bool" => GetBooleanValue(root, member) ? "true" : "false",
"int32" => GetInt32Value(root, member).ToString(CultureInfo.InvariantCulture),
"optional-string-array" => EngineContractUtilities.TryGetElement(root, member.SourcePath, out var optionalArray)
? CreateStringArrayExpression(optionalArray)
: "Array.Empty<string>()",
_ => throw new InvalidOperationException($"Unsupported clock-notation contract member kind '{member.Kind}'.")
};
static string CreateEnumValue(JsonElement root, EngineContractMember member)
{
if (member.EnumType is null)
{
throw new InvalidOperationException("Enum members require an enum type.");
}
return member.EnumType + "." + ToEnumMemberName(GetStringValue(root, member));
}
static bool GetBooleanValue(JsonElement root, EngineContractMember member)
{
if (EngineContractUtilities.TryGetElement(root, member.SourcePath, out var value) &&
value.ValueKind is JsonValueKind.True or JsonValueKind.False)
{
return value.GetBoolean();View on GitHub (pinned to ffc2b77c0f)
Solutions
- Check the engine contract JSON for the clock-notation engine named in the build error and verify all member Kind values are one of the six supported kinds.
- If a new kind is needed, add a case arm in the switch at TimeOnlyToClockNotationEngineContractFactory.cs:44 that emits the correct constructor argument expression.
- Fix any typo in the Kind string in the contract definition.
Example fix
// before — contract declares an unsupported kind
{ "kind": "double", "sourcePath": "clockNotation.precision" }
// after — use a supported kind or add a case in the factory
{ "kind": "int32", "sourcePath": "clockNotation.precision" } Defensive patterns
Strategy: validation
Validate before calling
// This is an internal contract/generator error. Prevent it by ensuring // every clock-notation engine contract member has a Kind value that the // factory supports: 'profile-object', 'string', 'enum', 'bool', 'int32', // or 'optional-string-array'. If a new kind is needed, add its case to // the switch at TimeOnlyToClockNotationEngineContractFactory.cs:44.
Prevention
- When adding a new member kind to a clock-notation engine contract, immediately add the corresponding case in CreateMemberValue.
- Keep the supported Kind set documented alongside the contract schema.
- Review contract JSON for typos in Kind strings.
When it happens
Trigger: An engine contract JSON in EngineContractCatalog declares a clock-notation member with a Kind value that the TimeOnlyToClockNotationEngineContractFactory does not handle. This is an internal contract/generator synchronization error, typically introduced when a new member kind is added to the contract schema without updating this factory.
Common situations: A Humanizer developer adds a new member kind (e.g. 'double', 'optional-int32') to a clock-notation engine contract but forgets to add the corresponding case in CreateMemberValue. Or a typo in the contract JSON produces an unrecognized kind string.
Related errors
- Missing required property '{sourcePath}'.
- A property path is required.
- Missing required property '{propertyName}'.
- Property '{propertyName}' must be an integer.
- Expected JSON array.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/ea563dd7edde7571.
Report an issue: GitHub.