Skip to content

Conversation

@dmitry-kandiner
Copy link

Binding of an IEnumerable in a nested positional record resulted in throwing of an InvalidOperationException from source generated code. The condition for emitting the code throwing the exception only worked with Arrays, and this fix applies the same logic for IEnumerable as well.

Fix #123422

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jan 27, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

@dmitry-kandiner
Copy link
Author

@dotnet-policy-service agree company="Growings RobotX Ltd."

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a regression in the configuration binder's source generator where binding IEnumerable<T> in nested positional records incorrectly threw an InvalidOperationException. The issue occurred because the code generation logic for handling empty collections and error conditions only checked for ArraySpec types, but not for IEnumerable<T> types.

Changes:

  • Updated the condition for emitting exception-throwing code to handle both ArraySpec and types with IsExactIEnumerableOfT property
  • Added a test case to verify that nested IEnumerable<T> in positional records can be bound successfully

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs Fixed the condition that determines when to emit if (member is null) vs else for exception throwing, now including IEnumerable<T> types alongside arrays
src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs Added test case TestBindingNestedIEnumerable to verify the fix works for the reported scenario
src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs Added test classes ContainingIEnumerable and NestedWithIEnumerable to support the new test case

@dmitry-kandiner dmitry-kandiner force-pushed the bugfix/issue-#123422 branch 2 times, most recently from 88da365 to ee73a21 Compare January 27, 2026 13:41
@tarekgh tarekgh added this to the 11.0.0 milestone Jan 27, 2026
@tarekgh tarekgh self-assigned this Jan 27, 2026
@jkotas jkotas changed the title Fixed codgen for IEnumerable<T> binding (#123422) Fixed codegen for IEnumerable<T> binding (#123422) Jan 27, 2026
Dmitry Kandiner added 2 commits January 27, 2026 19:11
Binding of an IEnumerable<T> in a nested positional record resulted in
throwing of an InvalidOperationException from source generated code.
The condition for emitting the code throwing the exception only worked
with Arrays, and this fix applies the same logic for IEnumerable<T> as
well.

Fix dotnet#123422

Signed-off-by: Dmitry Kandiner <dkandiner@growings.com>
Signed-off-by: Dmitry Kandiner <dkandiner@growings.com>
@tarekgh
Copy link
Member

tarekgh commented Jan 27, 2026

@dmitry-kandiner please don't force push again because this reset the review. Thanks!

@dmitry-kandiner
Copy link
Author

@dmitry-kandiner please don't force push again because this reset the review. Thanks!

Oops! I assumed not being lined up to the target branch will prevent merging. My mistake.

@tarekgh
Copy link
Member

tarekgh commented Jan 27, 2026

Oops! I assumed not being lined up to the target branch will prevent merging. My mistake.

No worries. We don't have to do that except if there is a merge conflict. Otherwise, every change in the PR will reset the CI run and takes longer to finish.

@dmitry-kandiner
Copy link
Author

@tarekgh could you please trigger re-build of the timed out tests?

@cincuranet
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

You have several pipelines (over 10) configured to build pull requests in this repository. Specify which pipelines you would like to run by using /azp run [pipelines] command. You can specify multiple pipelines using a comma separated list.

@azure-pipelines
Copy link

Supported commands
  • help:
    • Get descriptions, examples and documentation about supported commands
    • Example: help "command_name"
  • list:
    • List all pipelines for this repository using a comment.
    • Example: "list"
  • run:
    • Run all pipelines or specific pipelines for this repository using a comment. Use this command by itself to trigger all related pipelines, or specify specific pipelines to run.
    • Example: "run" or "run pipeline_name, pipeline_name, pipeline_name"
  • where:
    • Report back the Azure DevOps orgs that are related to this repository and org
    • Example: "where"

See additional documentation.

@dmitry-kandiner
Copy link
Author

/azp run runtime

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 123663 in repo dotnet/runtime

@tarekgh
Copy link
Member

tarekgh commented Jan 28, 2026

@dmitry-kandiner don't worry about the CI and don't have to merge your branch to main as you did, Anyway, I'll follow up and get this merged. I just need to do some local testing before merging it. Thanks again!

@dmitry-kandiner
Copy link
Author

@tarekgh Thank you! Apparently, the checks fail due to timeout, but I have no means to check what's going on exactly.

@tarekgh
Copy link
Member

tarekgh commented Jan 28, 2026

Yes, the timeout is known issue to us.

CC @markwilkie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Extensions-Configuration community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extensions.Configuration.Binder generated code fails on binding of IEnumerable<string> in a nested record.

3 participants