Skip to content

Fix infinite loop with multiple includes#5297

Merged
LTA-Thinking merged 8 commits intomainfrom
personal/rojo/fix-sort-include-2
Jan 13, 2026
Merged

Fix infinite loop with multiple includes#5297
LTA-Thinking merged 8 commits intomainfrom
personal/rojo/fix-sort-include-2

Conversation

@LTA-Thinking
Copy link
Contributor

@LTA-Thinking LTA-Thinking commented Dec 30, 2025

Description

When using multiple _include/_revinclude parameters in a search with _sort it is possible for the includes continuation tokens to get into an infinite loop if there are more than two pages of results. This happens because the included results are being sorted by surrogate id, when our logic is assuming it is being sorted by resource type id and then surrogate id.

Related issues

Addresses Bug 180045

Testing

New and existing E2E tests.

FHIR Team Checklist

  • Update the title of the PR to be succinct and less than 65 characters
  • Add a milestone to the PR for the sprint that it is merged (i.e. add S47)
  • Tag the PR with the type of update: Bug, Build, Dependencies, Enhancement, New-Feature or Documentation
  • Tag the PR with Open source, Azure API for FHIR (CosmosDB or common code) or Azure Healthcare APIs (SQL or common code) to specify where this change is intended to be released.
  • Tag the PR with Schema Version backward compatible or Schema Version backward incompatible or Schema Version unchanged if this adds or updates Sql script which is/is not backward compatible with the code.
  • When changing or adding behavior, if your code modifies the system design or changes design assumptions, please create and include an ADR.
  • CI is green before merge Build Status
  • Review squash-merge requirements

Semver Change (docs)

Patch|Skip|Feature|Breaking (reason)

@LTA-Thinking LTA-Thinking requested a review from a team as a code owner December 30, 2025 19:57
@LTA-Thinking LTA-Thinking added this to the FY26\Q2\2Wk\2Wk13 milestone Dec 30, 2025
@LTA-Thinking LTA-Thinking added Bug Bug bug bug. Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs labels Dec 30, 2025
SergeyGaluzo
SergeyGaluzo previously approved these changes Dec 30, 2025
@LTA-Thinking
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservations(tag);
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);

Check warning

Code scanning / CodeQL

Useless assignment to local variable

This assignment to [resources](1) is useless, since its value is never read.

Copilot Autofix

AI about 2 months ago

In general, to fix a useless assignment where the right-hand side has important side effects, you keep the call but remove the unused local variable. If the result is truly not needed, you should either discard it with _ or simply await the method without assigning the result. This preserves behavior while eliminating dead code and any confusion about the variable’s purpose.

For this specific case in test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs, in the method GivenPatientsWithIncludedResourcesGreaterThanOnePage_WhenSearchedWithSortAndInclude_ThenSearchResultsContainIncludedResources, change line 1156 from assigning to resources to just awaiting the method call. You do not need any new imports or additional methods. The minimal change is:

  • Replace var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag); with await CreatePatientsWithLinkedObservationAndEncounter(tag);.

This keeps the creation of patients, observations, and encounters (the side effect) while removing the unused local variable, without affecting existing test behavior.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
@@ -1153,7 +1153,7 @@
         public async Task GivenPatientsWithIncludedResourcesGreaterThanOnePage_WhenSearchedWithSortAndInclude_ThenSearchResultsContainIncludedResources(string sortParameterName)
         {
             var tag = Guid.NewGuid().ToString();
-            var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
+            await CreatePatientsWithLinkedObservationAndEncounter(tag);
 
             var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sortParameterName}&_revinclude=Observation:subject&_count=10&_includesCount=8");
 
EOF
@@ -1153,7 +1153,7 @@
public async Task GivenPatientsWithIncludedResourcesGreaterThanOnePage_WhenSearchedWithSortAndInclude_ThenSearchResultsContainIncludedResources(string sortParameterName)
{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
await CreatePatientsWithLinkedObservationAndEncounter(tag);

var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sortParameterName}&_revinclude=Observation:subject&_count=10&_includesCount=8");

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservations(tag);
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);

Check warning

Code scanning / CodeQL

Useless assignment to local variable

This assignment to [resources](1) is useless, since its value is never read.

Copilot Autofix

AI about 2 months ago

To fix this, we should keep calling CreatePatientsWithLinkedObservationAndEncounter(tag) (to preserve its side effects of creating linked resources) but remove the unnecessary assignment to the unused local variable resources. In general, when a method is called purely for its side effects and the return value is never used, we should either not capture the return value or use the discard _ if we want to emphasize that it is intentionally unused.

Specifically in test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs, inside the method GivenPatientsWithIncludedResources_WhenSearchedWithSortAndIncludeOnDataThatOnlyPartiallyContainsTheSortField_ThenTheRightIncludedResourcesAreReturned, replace the line:

var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);

with:

await CreatePatientsWithLinkedObservationAndEncounter(tag);

No new imports or helper methods are required. This preserves all existing functionality while eliminating the useless assignment that CodeQL flagged.

Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
@@ -1185,7 +1185,7 @@
         public async Task GivenPatientsWithIncludedResources_WhenSearchedWithSortAndIncludeOnDataThatOnlyPartiallyContainsTheSortField_ThenTheRightIncludedResourcesAreReturned(string sortParameterName, int expectedCount)
         {
             var tag = Guid.NewGuid().ToString();
-            var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
+            await CreatePatientsWithLinkedObservationAndEncounter(tag);
 
             var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sortParameterName}&_revinclude=Observation:subject&_count={expectedCount}");
 
EOF
@@ -1185,7 +1185,7 @@
public async Task GivenPatientsWithIncludedResources_WhenSearchedWithSortAndIncludeOnDataThatOnlyPartiallyContainsTheSortField_ThenTheRightIncludedResourcesAreReturned(string sortParameterName, int expectedCount)
{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
await CreatePatientsWithLinkedObservationAndEncounter(tag);

var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sortParameterName}&_revinclude=Observation:subject&_count={expectedCount}");

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservations(tag);
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);

Check warning

Code scanning / CodeQL

Useless assignment to local variable

This assignment to [resources](1) is useless, since its value is never read.

Copilot Autofix

AI about 2 months ago

To fix this, we should keep the call to CreatePatientsWithLinkedObservationAndEncounter(tag) (for its side effects of creating test data) but remove the unused local variable resources. In C#, the simplest way is to either call the method without capturing its return value, or assign it to the discard _. Both approaches eliminate the useless assignment while preserving behavior.

The most direct change, with minimal impact, is in test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs inside GivenPatientsWithIncludedResources_WhenSearchedWithSortAndInclude_ThenTheSecondPhaseContinuationTokenIsReturned. Replace:

var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);

with:

await CreatePatientsWithLinkedObservationAndEncounter(tag);

No new imports, methods, or additional definitions are required; we are only changing how the existing method call is made so that the unused variable is removed.


Suggested changeset 1
test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
--- a/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
+++ b/test/Microsoft.Health.Fhir.Shared.Tests.E2E/Rest/Search/SortTests.cs
@@ -1204,7 +1204,7 @@
         public async Task GivenPatientsWithIncludedResources_WhenSearchedWithSortAndInclude_ThenTheSecondPhaseContinuationTokenIsReturned(int includesCount, string sort)
         {
             var tag = Guid.NewGuid().ToString();
-            var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
+            await CreatePatientsWithLinkedObservationAndEncounter(tag);
 
             var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sort}&_revinclude=Observation:subject&_revinclude=Encounter:subject&_count=12&_includesCount={includesCount}");
             var relatedLink = response.Resource.Link.FirstOrDefault(link => link.Relation.Equals("related", StringComparison.OrdinalIgnoreCase));
EOF
@@ -1204,7 +1204,7 @@
public async Task GivenPatientsWithIncludedResources_WhenSearchedWithSortAndInclude_ThenTheSecondPhaseContinuationTokenIsReturned(int includesCount, string sort)
{
var tag = Guid.NewGuid().ToString();
var resources = await CreatePatientsWithLinkedObservationAndEncounter(tag);
await CreatePatientsWithLinkedObservationAndEncounter(tag);

var response = await Client.SearchAsync($"Patient?_tag={tag}&_sort={sort}&_revinclude=Observation:subject&_revinclude=Encounter:subject&_count=12&_includesCount={includesCount}");
var relatedLink = response.Resource.Link.FirstOrDefault(link => link.Relation.Equals("related", StringComparison.OrdinalIgnoreCase));
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
@LTA-Thinking
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@LTA-Thinking
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

rbans96
rbans96 previously approved these changes Jan 12, 2026
@LTA-Thinking LTA-Thinking enabled auto-merge (squash) January 12, 2026 23:05
@LTA-Thinking LTA-Thinking merged commit 6dd540c into main Jan 13, 2026
60 of 61 checks passed
@LTA-Thinking LTA-Thinking deleted the personal/rojo/fix-sort-include-2 branch January 13, 2026 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Bug Bug bug bug. No-PaaS-breaking-change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants