Skip to content

Fix StackOverflowException when serializing complex exceptions#3305

Draft
Copilot wants to merge 3 commits intodevfrom
copilot/fix-csvhelper-fieldvalidationexception
Draft

Fix StackOverflowException when serializing complex exceptions#3305
Copilot wants to merge 3 commits intodevfrom
copilot/fix-csvhelper-fieldvalidationexception

Conversation

Copy link
Contributor

Copilot AI commented Jan 5, 2026

Summary

What changed?

  • Modified ErrorSerializerSettingsFactory.ExceptionResolver to use an allowlist approach for exception property serialization
  • Only serialize well-known safe properties: Message, StackTrace, Source, HelpLink, HResult, Data, InnerException
  • Added MaxDepth=64 as an additional safety measure
  • Added unit tests for exception serialization behavior

Why is this change needed?

Exceptions with complex/deeply nested properties (e.g., CsvHelper's FieldValidationException containing ReadingContext with the entire CSV reader state) cause infinite recursion during JSON serialization. ReferenceLoopHandling.Ignore only handles true circular references (same object instance), not deep object graphs. StackOverflowException cannot be caught, crashing the process.

Issues / work items


Project checklist

  • Documentation changes are not required
  • Release notes are not required for the next release
  • Backport is not required
  • All required tests have been added/updated (unit tests, E2E tests)
  • No extra work is required to be leveraged by OutOfProc SDKs
  • No change to the version of the WebJobs.Extensions.DurableTask package
  • No EventIds were added to EventSource logs
  • This change should be added to the v2.x branch
  • Breaking change?

AI-assisted code disclosure (required)

Was an AI tool used? (select one)

  • No
  • Yes, AI helped write parts of this PR (e.g., GitHub Copilot)
  • Yes, an AI agent generated most of this PR

If AI was used:

  • Tool(s): GitHub Copilot
  • AI-assisted areas/files: ErrorSerializerSettingsFactory.cs, ErrorSerializerSettingsFactoryTests.cs
  • What you changed after AI output: N/A - AI agent completed the work

AI verification (required if AI was used):

  • I understand the code and can explain it
  • I verified referenced APIs/types exist and are correct
  • I reviewed edge cases/failure paths (timeouts, retries, cancellation, exceptions)
  • I reviewed concurrency/async behavior
  • I checked for unintended breaking or behavior changes

Testing

Automated tests

  • Result: Passed (8 new unit tests for ErrorSerializerSettingsFactoryTests)

Manual validation (only if runtime/behavior changed)

  • N/A - validated through unit tests simulating problematic exception patterns

Notes for reviewers

  • This is a behavioral change: derived exception properties beyond the allowlist will no longer be serialized. This is intentional—those properties are the source of the serialization issues.
  • The allowlist covers all standard System.Exception properties needed for debugging/diagnostics.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • azfunc.pkgs.visualstudio.com
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.23.8/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp /opt/hostedtoolcache/CodeQL/2.23.8/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>CsvHelper FieldValidationException & Orchestrator throws StackOverflowException</issue_title>
<issue_description>I'm parsing a csv file with CsvHelper with bad data in it.

I have a StackOverflowException

[19-Dec-18 14:06:32] Executing 'Activity' (Reason='', Id=18c5e63e-6798-484c-b08d-2a304b110168)
[19-Dec-18 14:06:32] Bad date
[19-Dec-18 14:06:32] Anonymously Hosted DynamicMethods Assembly: Exception of type 'CsvHelper.FieldValidationException' was thrown.
[19-Dec-18 14:06:32] Executed 'Activity' (Failed, Id=18c5e63e-6798-484c-b08d-2a304b110168)
[19-Dec-18 14:06:32] System.Private.CoreLib: Exception while executing function: Activity. Anonymously Hosted DynamicMethods Assembly: Exception of type 'CsvHelper.FieldValidationException' was thrown.
[19-Dec-18 14:06:32] da62c5035f914ffbb221f22953279497: Function 'Activity (Activity)' failed with an error. Reason: CsvHelper.FieldValidationException: Exception of type 'CsvHelper.FieldValidationException' was thrown.
[19-Dec-18 14:06:32] at lambda_method(Closure )
[19-Dec-18 14:06:32] at CsvHelper.Expressions.RecordCreator.CreateT
[19-Dec-18 14:06:32] at CsvHelper.Expressions.RecordManager.CreateT
[19-Dec-18 14:06:32] at CsvHelper.CsvReader.GetRecordsT+MoveNext()
[19-Dec-18 14:06:32] at System.Collections.Generic.List1.AddEnumerable(IEnumerable1 enumerable)
[19-Dec-18 14:06:32] at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
[19-Dec-18 14:06:32] at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) [19-Dec-18 14:06:32] at SOE.Activity.Run(Object obj, ILogger log) in C:\dev [soe.zip](https://github.com/Azure/azure-functions-durable-extension/files/2695153/soe.zip) \soe\SOE\Activity.cs:line 22 [19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker2.InvokeAsync(TReflected instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\VoidTaskMethodInvoker.cs:line 20
[19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 63
[19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 556
[19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 503
[19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 439
[19-Dec-18 14:06:32] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 249. IsReplay: False. State: Failed. HubName: DurableFunctionsHub. AppName: . SlotName: . ExtensionVersion: 1.7.0. SequenceNumber: 7.
[19-Dec-18 14:06:32] Host lock lease acquired by instance ID '0000000000000000000000009EA34753'.
Process is terminating due to StackOverflowException.
Press any key to continue . . .

You have a simple project attached to reproduce the issue.

soe.zip
</issue_description>

<agent_instructions>check if this issue still exists, if so fix it</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@cgillum Thanks for this report and for the reference project. I was able to reproduce the issue. It looks like a bug in our exception serialization code. @cgillum The problem is `FieldValidationException`. It's a complex data structure and the Json.NET serializer we use runs into a `StackOverflowExcepti...

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Modified ErrorSerializerSettingsFactory to only serialize safe, well-known
exception properties (Message, StackTrace, Source, HelpLink, HResult, Data,
InnerException). This prevents serialization of complex properties from
derived exception types like CsvHelper.FieldValidationException that can
cause infinite recursion and StackOverflowException during JSON serialization.

Also added MaxDepth=64 as an additional safety measure.

Fixes #550

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Extracted CreateThrownException helper method to reduce code duplication
in ErrorSerializerSettingsFactoryTests.

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix CsvHelper FieldValidationException and StackOverflowException Fix StackOverflowException when serializing complex exceptions Jan 5, 2026
Copilot AI requested a review from YunchuWang January 5, 2026 22:49
Comment on lines +190 to +193
catch (Exception ex)
{
return ex;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CsvHelper FieldValidationException & Orchestrator throws StackOverflowException

2 participants