microsoft/autogen · error · InvalidOperationException

The group chat has not been initialized. It must be run befo

Error message

The group chat has not been initialized. It must be run before it can be saved.

What it means

GroupChatBase.SaveStateAsync serializes the team's runtime state, but that state (runtimeLayer.HasRunOnce) only exists after the team has been initialized by a run. Calling SaveStateAsync on a freshly constructed group chat throws InvalidOperationException telling you the chat must be run at least once before saving.

Source

Thrown at dotnet/src/Microsoft.AutoGen/AgentChat/GroupChat/GroupChatBase.cs:305

        {
            this.OutputSink?.Reset();
        }
    }

    public ValueTask ResetAsync(CancellationToken cancel)
    {
        const string TaskAlreadyRunning = "The group chat is currently running. It must be stopped before it can be reset.";
        return this.RunManager.RunAsync(
            this.ResetInternalAsync,
            cancel,
            message: TaskAlreadyRunning);
    }

    public ValueTask<JsonElement> SaveStateAsync()
    {
        if (!this.runtimeLayer.HasRunOnce)
        {
            throw new InvalidOperationException("The group chat has not been initialized. It must be run before it can be saved.");
        }

        const string TaskAlreadyRunning = "The team cannot be saved while it is running.";
        return this.RunManager.RunAsync(
            SaveStateInternalAsync,
            CancellationToken.None, // TODO: Change this API?
            message: TaskAlreadyRunning);

        async ValueTask<JsonElement> SaveStateInternalAsync(CancellationToken _)
        {
            TeamState teamState = new()
            {
                TeamId = this.TeamId,
                RuntimeState = await this.Runtime!.SaveStateAsync(),
            };

            JsonElement result = SerializedState.Create(teamState).AsJson();

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Run the team once (even with an empty/minimal task) before calling SaveStateAsync
  2. For 'initial state' persistence, persist your own construction inputs (team definition) instead of SaveStateAsync
  3. Check the team has run before saving, and handle this exception in checkpoint code as 'nothing to save yet'

Example fix

// before
var team = new RoundRobinGroupChat(agents, manager);
var state = await team.SaveStateAsync(); // throws
// after
await foreach (var _ in team.StreamAsync("start", cancellationToken)) { break; } // initialize
var state = await team.SaveStateAsync();
Defensive patterns

Strategy: validation

Validate before calling

// No public HasRunOnce; approximate by tracking whether you have run the team yourself
if (!hasRunAtLeastOnce)
{
    await foreach (var _ in team.StreamAsync("init", ct)) { break; } // force initialization
    hasRunAtLeastOnce = true;
}
var state = await team.SaveStateAsync();

Try / catch

catch (InvalidOperationException ex) when (ex.Message.Contains("must be run before it can be saved"))
{
    // nothing to checkpoint yet: skip saving, or run the team once to initialize it
}

Prevention

When it happens

Trigger: Creating a team (e.g. RoundRobinGroupChat / graph chat) and immediately calling SaveStateAsync() before any RunAsync/StreamAsync call; or after a reset that cleared the runtime layer.

Common situations: Implementing checkpoint-on-start patterns (save initial state before running) which this API does not support; resuming logic that saves unconditionally; calling save after a failed/aborted first run that never completed initialization.

Related errors


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