reactiveui/refit · error · JsonException

Unexpected token {reader.TokenType} when parsing {typeof(TEn

Error message

Unexpected token {reader.TokenType} when parsing {typeof(TEnum)}.

What it means

Thrown by CamelCaseStringEnumConverter.ReadValue when the current JSON token is neither a string/property-name nor a number — e.g. true/false, null, start of object/array. The converter only knows how to map strings (names) and numbers (underlying values) to enum fields, so any other token type is an error.

Source

Thrown at src/Refit/CamelCaseStringEnumConverter.cs:229

                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>
        private readonly EnumConverter<TEnum> _inner = new();

        /// <inheritdoc/>
        public override TEnum? Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options) =>
            IsNullOrEmptyString(ref reader) ? null : _inner.Read(ref reader, typeof(TEnum), options);

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Correct the JSON to send a valid enum name (string) or numeric value for the field.
  2. If the field can legitimately be absent, make the property a nullable enum (MyEnum?) so null is tolerated by the nullable converter.
  3. If the source genuinely sends a non-string/number, change the receiving type (e.g. bool) or pre-transform the JSON.

Example fix

// before — non-nullable enum receives a boolean token
public sealed record Payload(Status Status);
// JSON: { "status": true }  -> throws Unexpected token True

// after — correct the payload type, or make nullable if absent is valid
public sealed record Payload(Status? Status);
// and send { "status": "active" } or { "status": 1 }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the JSON token type for enum fields before deserializing.
using var doc = JsonDocument.Parse(json);
if (doc.RootElement.TryGetProperty("status", out var el)
    && el.ValueKind is not (JsonValueKind.String or JsonValueKind.Number))
{
    throw new InvalidDataException("status must be a string or number.");
}

Try / catch

try { return JsonSerializer.Deserialize<Payload>(json); }
catch (JsonException ex) when (ex.Message.Contains("Unexpected token"))
{ /* wrong token type for enum — fix payload or DTO type */ }

Prevention

When it happens

Trigger: The JSON for an enum field is a boolean, null, object, or array rather than a string or number, e.g. `{ "status": true }` or `{ "status": null }` (for a non-nullable enum) or `{ "status": {} }`.

Common situations: Server changes a field's type (e.g. from a string code to a boolean flag); a non-nullable enum receiving JSON null; malformed/inconsistent payloads; schema drift after an API change.

Understand the failure class

Related errors


AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13). Data as JSON: /api/errors/4f72618895fb23f6. Report an issue: GitHub.