microsoft/autogen · error · InvalidOperationException

Cannot deserialize state to {typeof(T)}.

Error message

Cannot deserialize state to {typeof(T)}.

What it means

SerializedState.As<T>() throws InvalidOperationException when JsonSerializer.Deserialize<T> on the stored JsonElement returns null. System.Text.Json returns null only when the payload is the literal JSON null (or a nullable type deserialized to null), so this indicates the persisted state JSON is null-valued rather than absent — the element exists but carries no data.

Source

Thrown at dotnet/src/Microsoft.AutoGen/AgentChat/State/SerializedState.cs:76

    public T As<T>()
    {
        if (this.deserializedValue is T value)
        {
            return value;
        }

        if (this.deserializedValue != null)
        {
            throw new InvalidOperationException($"Cannot convert state of type {this.deserializedValue.GetType()} to {typeof(T)}.");
        }

        if (this.jsonValue == null)
        {
            throw new InvalidOperationException("State is not initialized.");
        }

        T? result = JsonSerializer.Deserialize<T>(this.jsonValue!.Value, SerializerOptions)
                    ?? throw new InvalidOperationException($"Cannot deserialize state to {typeof(T)}.");

        this.deserializedValue = result;

        return result;
    }

    private object? deserializedValue;
    private JsonElement? jsonValue;

    private SerializedState(object state)
    {
        this.deserializedValue = state;
    }

    public SerializedState(JsonElement json)
    {
        this.jsonValue = json;
    }

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. On the save side, skip writing state when the value is null instead of writing JSON null.
  2. On the load side, treat JSON-null state as 'no state' (check jsonValue.Value.ValueKind == JsonValueKind.Null) and fall back to a default instance.
  3. Validate checkpoint content after external edits or migrations.

Example fix

// before
// persisted: { "state": null }
var s = serializedState.As<MyState>(); // Deserialize returns null -> throws

// after
var s = (serializedState.AsJson().ValueKind == JsonValueKind.Null)
    ? new MyState()
    : serializedState.As<MyState>();
Defensive patterns

Strategy: validation

Validate before calling

bool IsNullPayload(SerializedState s) =>
    s.AsJsonWorks() && s.AsJson().ValueKind == JsonValueKind.Null;
// check ValueKind == JsonValueKind.Null before calling As<T>

Try / catch

try { return s.As<T>(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot deserialize state"))
{ /* persisted JSON null; supply default */ }

Prevention

When it happens

Trigger: The stored JsonElement is JsonValueKind.Null (e.g. persisted state was written as "state": null) and As<T>() is called; also possible for nullable T where the converter yields null.

Common situations: A save path that serialized a null state (agent crashed or had nothing to save, wrote null instead of skipping); JSON transforms that null out optional members; mixing serializers where null round-trips differently.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/7c99cce00ab3ac0e. Report an issue: GitHub.