reactiveui/refit · error · JsonException
Unable to convert '{value}' to {typeof(TEnum)}.
Error message
Unable to convert '{value}' to {typeof(TEnum)}. What it means
Thrown by CamelCaseStringEnumConverter when the JSON string token's value does not match any enum field name (case-sensitively or insensitively) and is not numeric. The converter tried both the exact-name and ignore-case maps and found nothing, so it cannot produce a valid enum value and raises a JsonException naming the bad value.
Source
Thrown at src/Refit/CamelCaseStringEnumConverter.cs:221
if (reader.TokenType is JsonTokenType.String or JsonTokenType.PropertyName)
{
var value = reader.GetString();
if (value is null || string.IsNullOrWhiteSpace(value))
{
throw new JsonException($"Cannot convert an empty value to {typeof(TEnum)}.");
}
if (_namesToValues.TryGetValue(value!, out var namedValue))
{
return namedValue;
}
if (_namesToValuesIgnoreCase.TryGetValue(value!, out var namedValueIgnoreCase))
{
return namedValueIgnoreCase;
}
throw new JsonException($"Unable to convert '{value}' to {typeof(TEnum)}.");
}
if (reader.TokenType == JsonTokenType.Number)
{
return EnumHelpers.Info<TEnum>.ReadJsonNumericValue(ref reader);
}
throw new JsonException($"Unexpected token {reader.TokenType} when parsing {typeof(TEnum)}.");
}
}
/// <summary>A strongly-typed JSON converter for nullable enums that maps values to and from camelCase names.</summary>
/// <typeparam name="TEnum">The underlying enum type.</typeparam>
internal sealed class NullableEnumConverter<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum> : JsonConverter<TEnum?>
where TEnum : struct, Enum
{
/// <summary>The underlying non-nullable enum converter that performs the name/value mapping.</summary>View on GitHub (pinned to b455f65ecc)
Solutions
- Align the JSON value with a valid enum field name, respecting the camelCase naming the converter expects (or configure the converter's naming policy).
- If the client may receive unknown values, deserialize into the enum backed by JsonStringEnumConverter with a fallback, or use a string property plus manual parsing with Enum.TryParse.
- Resolve version skew by adding the missing enum member or normalizing the source value.
Example fix
// before — enum mismatch / typo
public enum Status { Active, Inactive }
// JSON: { "status": "actv" } -> throws
// after — correct camelCase name (or add [JsonStringEnumName])
// JSON: { "status": "active" }
// or parse defensively:
var raw = JsonDocument.Parse(json).RootElement.GetProperty("status").GetString();
if (Enum.TryParse<Status>(raw, ignoreCase: true, out var s)) { /* use s */ } Defensive patterns
Strategy: validation
Validate before calling
// Validate a value maps to the enum before deserializing the whole payload.
static bool IsKnownEnumName<TEnum>(string? name) where TEnum : struct, Enum =>
name is not null && Enum.TryParse<TEnum>(name, ignoreCase: true, out _);
// or: keep a whitelist of valid camelCase names
static readonly HashSet<string> Valid = new(Enum.GetNames<Status>().Select(CamelCase)); Type guard
// Loose-parse guard using the underlying enum.
static bool TryReadEnum<TEnum>(string? raw, out TEnum value) where TEnum : struct, Enum =>
Enum.TryParse(raw, ignoreCase: true, out value); Try / catch
try { return JsonSerializer.Deserialize<Payload>(json); }
catch (JsonException ex) when (ex.Message.Contains("Unable to convert"))
{ /* unknown enum value — log and use a default/Unknown member */ } Prevention
- Align client and server enum naming; respect the converter's camelCase policy.
- Reserve an explicit Unknown/default enum member for unrecognized values when the source is untrusted.
- Parse defensively into a string then Enum.TryParse when you must tolerate drift.
When it happens
Trigger: Deserializing an enum from a JSON string whose name doesn't exist, e.g. enum Status { Active, Inactive } and JSON `{ "status": "Actv" }` (typo) or `{ "status": "PENDING" }` (wrong casing/variant). The camelCase mapping also matters: names are matched against the camelCased enum field names.
Common situations: Server/client enum naming drift (e.g. server sends snake_case or SCREAMING_CASE while converter expects camelCase); typos; a new enum value the client doesn't have yet (version skew); sending a display label instead of the code name.
Related errors
- Cannot convert an empty value to {typeof(TEnum)}.
- Unexpected token {reader.TokenType} when parsing {typeof(TEn
- Unsupported enum backing type for {typeof(TEnum)}.
- Enum {typeof(TEnum)} does not use a signed backing type.
- Enum {typeof(TEnum)} does not use an unsigned backing type.
AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13).
Data as JSON: /api/errors/33888ecd8d702514.
Report an issue: GitHub.