microsoft/autogen · error · ArgumentException

From mismatch

Error message

From mismatch

What it means

ToolCallMessage.Update(ToolCallMessageUpdate) first verifies the update comes from the same agent: if update.From != this.From it throws ArgumentException('From mismatch', paramName: update). During function-call streaming, chunks of one tool call must be attributed to a single agent; a chunk from a different sender would corrupt the accumulated arguments. Like TextMessage, null vs non-null From also counts as a mismatch.

Source

Thrown at dotnet/src/AutoGen.Core/Message/ToolCallMessage.cs:64

    public ToolCallMessage(string functionName, string functionArgs, string? from = null)
    {
        this.From = from;
        this.ToolCalls = new List<ToolCall> { new ToolCall(functionName, functionArgs) { ToolCallId = functionName } };
    }

    public ToolCallMessage(ToolCallMessageUpdate update)
    {
        this.From = update.From;
        this.ToolCalls = new List<ToolCall> { new ToolCall(update.FunctionName, update.FunctionArgumentUpdate) };
    }

    public void Update(ToolCallMessageUpdate update)
    {
        // firstly, valid if the update is from the same agent
        if (update.From != this.From)
        {
            throw new System.ArgumentException("From mismatch", nameof(update));
        }

        // if update.FunctionName exists in the tool calls, update the function arguments
        var toolCall = this.ToolCalls.FirstOrDefault(tc => tc.FunctionName == update.FunctionName);
        if (toolCall is not null)
        {
            toolCall.FunctionArguments += update.FunctionArgumentUpdate;
        }
        else
        {
            this.ToolCalls.Add(new ToolCall(update.FunctionName, update.FunctionArgumentUpdate));
        }
    }

    public IList<ToolCall> ToolCalls { get; set; }

    public string? From { get; set; }

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Set From to the agent name on the seed ToolCallMessage and on every ToolCallMessageUpdate.
  2. Key tool-call accumulators by From (and function name) so chunks from different agents stay separate.
  3. If the seed's From is null and updates carry a name, recreate the ToolCallMessage from the first named update.
  4. When broadcasting updates in group chat loops, create a fresh accumulator per agent turn.

Example fix

// before
var msg = new ToolCallMessage(new ToolCallMessageUpdate("fn", "{") { From = null });
msg.Update(new ToolCallMessageUpdate("fn", "\"a\":1}") { From = "assistant" }); // throws

// after
var msg = new ToolCallMessage(new ToolCallMessageUpdate("fn", "{") { From = "assistant" });
msg.Update(new ToolCallMessageUpdate("fn", "\"a\":1}") { From = "assistant" });
Defensive patterns

Strategy: validation

Validate before calling

if (update.From != msg.From)
    throw new StreamingException($"Tool-call chunk From '{update.From}' != message From '{msg.From}'");
msg.Update(update);

Type guard

static bool IsSameToolCallSender(ToolCallMessage msg, ToolCallMessageUpdate update) => update.From == msg.From;

Try / catch

try { toolMsg.Update(update); }
catch (ArgumentException ex) when (ex.Message.Contains("From mismatch"))
{
    toolMsg = new ToolCallMessage(update); // different sender: start its own accumulation
}

Prevention

When it happens

Trigger: Seeded ToolCallMessage with From = null (via new ToolCallMessage(update) where update.From was null) then applying updates with From = "assistant"; interleave chunks from two function-calling agents into one accumulator; middleware that stamps From on some chunks only.

Common situations: Streaming function-call arguments where the first chunk arrives from raw infrastructure (no agent tag) and subsequent chunks are agent-attributed; group-chat broadcast loops forwarding tool-call updates from multiple agents through shared state.

Related errors


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