microsoft/autogen · error · InvalidOperationException

Cannot convert state of type {this.deserializedValue.GetType

Error message

Cannot convert state of type {this.deserializedValue.GetType()} to {typeof(T)}.

What it means

SerializedState.As<T>() throws InvalidOperationException when the stored value's runtime type is not compatible with T. The method first tries a direct CLR cast (deserializedValue is T); if the stored object exists but the cast fails, this exception is thrown before any JSON round-trip is attempted — so this is a hard type mismatch, not a serialization problem.

Source

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

        this.jsonValue = JsonSerializer.SerializeToElement(this.deserializedValue, SerializerOptions);
        return this.jsonValue.Value;
    }

    public static SerializedState Create<T>(T state) where T : notnull
    {
        return new SerializedState((object)state);
    }

    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;

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Match T to the exact type used when the state was created/saved (inspect the checkpoint JSON to see the real shape).
  2. If the underlying representation is JSON (jsonValue path), As<T> can deserialize — so for cross-type loading, load from the JSON representation rather than Create-typed objects.
  3. Bump or clear persisted checkpoints after changing state types; add a state version field.

Example fix

// before
var state = SerializedState.Create(new PlannerState { Plan = "..." });
string s = state.As<string>(); // throws: type is PlannerState, not string

// after
var state = SerializedState.Create(new PlannerState { Plan = "..." });
PlannerState s = state.As<PlannerState>();
Defensive patterns

Strategy: validation

Validate before calling

// Before As<T>, confirm the stored representation can satisfy T:
// if you control the writer, assert type equality at save time and record the type name alongside.
if (savedTypeName != typeof(T).FullName) { /* load as JSON or re-create checkpoint */ }

Try / catch

try { return state.As<T>(); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Cannot convert state"))
{ /* type drift: migrate or fall back to default state */ }

Prevention

When it happens

Trigger: Calling As<string>() on state created via SerializedState.Create(new MyState()), or As<MyStateA>() when the checkpoint was saved from a different state type MyStateB. Any As<T> where T differs from the concrete type used at Create time.

Common situations: Changing the Team/Agent state class between development iterations while reusing old checkpoints; multiple agents sharing a state key with different expected types; copy-pasting LoadState/SaveState code between agents.

Related errors


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