{"record":{"id":"08e610fe84809b6d","repo":"microsoft/autogen","slug":"from-mismatch","errorCode":null,"errorMessage":"From mismatch","messagePattern":"From mismatch","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.Core/Message/TextMessage.cs","lineNumber":31,"sourceCode":"    }\n\n    public TextMessage(TextMessageUpdate update)\n    {\n        this.Content = update.Content ?? string.Empty;\n        this.Role = update.Role;\n        this.From = update.From;\n    }\n\n    public void Update(TextMessageUpdate update)\n    {\n        if (update.Role != this.Role)\n        {\n            throw new System.ArgumentException(\"Role mismatch\", nameof(update));\n        }\n\n        if (update.From != this.From)\n        {\n            throw new System.ArgumentException(\"From mismatch\", nameof(update));\n        }\n\n        this.Content = this.Content + update.Content ?? string.Empty;\n    }\n\n    public Role Role { get; set; }\n\n    public string Content { get; set; }\n\n    public string? From { get; set; }\n\n    public override string ToString()\n    {\n        return $\"TextMessage({this.Role}, {this.Content}, {this.From})\";\n    }\n\n    public string? GetContent()\n    {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.Core/Message/TextMessage.cs#L13-L49","documentation":"TextMessage.Update(TextMessageUpdate) also requires update.From to equal the message's current From; a mismatch throws ArgumentException('From mismatch', paramName: update). It ensures streamed chunks all originate from the same agent so attribution cannot silently change mid-stream. Note From is nullable: null == null passes, but null vs \"agent\" fails.","triggerScenarios":"First chunk has From = null (created via new TextMessage(update) where update.From was null) and later chunks carry From = \"assistant\"; interleaving chunks from two agents into one accumulator; middleware that sets From on outgoing chunks but not the initial one.","commonSituations":"Streaming middleware that enriches messages with From after creation; constructing the seed TextMessage from a raw completion (no From) and applying updates from agent-tagged events; concurrent agents writing into a shared streaming buffer.","solutions":["Set From consistently (either always null or always the agent name) on the seed message and every update.","Initialize the accumulator from the first update including its From rather than from a bare completion.","Key accumulators by From (and Role) so chunks from different senders never meet in one Update call.","Normalize before updating: if msg.From is null and update.From is set, recreate the message with the update's From."],"exampleFix":"// before\nvar msg = new TextMessage(Role.Assistant, \"\", from: null);\nmsg.Update(new TextMessageUpdate(Role.Assistant, \"delta\") { From = \"assistant\" }); // throws\n\n// after\nvar msg = new TextMessage(Role.Assistant, \"\", from: \"assistant\");\nmsg.Update(new TextMessageUpdate(Role.Assistant, \"delta\") { From = \"assistant\" });","handlingStrategy":"validation","validationCode":"if (update.From != msg.From)\n{\n    if (msg.From is null && msg.Content.Length == 0) msg = new TextMessage(update);\n    else throw new StreamingException($\"Chunk From '{update.From}' != message From '{msg.From}'\");\n}\nelse msg.Update(update);","typeGuard":"static bool IsSameSender(TextMessage msg, TextMessageUpdate update) => update.From == msg.From;","tryCatchPattern":"try { msg.Update(update); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"From mismatch\"))\n{\n    // route chunk to the accumulator keyed by update.From instead\n}","preventionTips":["Set From consistently on the seed message and every update (never mix null and a name).","Create the seed TextMessage from the first update, not from a bare completion lacking From.","Maintain per-agent accumulators in concurrent streaming scenarios."],"tags":["autogen","dotnet","message","streaming","text-message","from-mismatch","argumentexception"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}