Describe the bug
When a Bundle is submitted to IFhirService.TransactionAsync having PUT (update) entries bearing an ifMatch requirement in their RequestComponent, the updates are processed irrespective of the target resources' version.
As a result, this invisibly enables lost updates during transactions, which the ifMatch requirement seeks to avoid.
To Reproduce
Steps to reproduce the behavior:
Using Hl7.Fhir.R4 NuGet package...
- Create a new FHIR resource of any desired type in your Spark FHIR server.
- Retrieve its current version.
- Modify it.
- Create a transaction builder using the
FhirClient's endpoint. (e.g., new TransactionBuilder(fhirClient.Endpoint, BundleType.Transaction)).
- Add the modified resource to the transaction builder using its
.Update() method. You must include a versionId manually to ensure the ifMatch header is included. (e.g., transactionBuilder.Update(resource, "not-the-real-resource-version")). Note that the version specified must vary from the server's version in order to properly test this bug.
- Create a
Bundle from the TransactionBuilder (transactionBuilder.ToBundle()). (You should be able to verify the entry header by examining the resulting bundle.Entry[].Request.IfMatch property—which should have a value containing a weak ETag equivalent of the non-matching version specified in step 5.)
- Send it to a Spark FHIR server (using
fhirClient.TransactionAsync()).
- Receive a successful response with a modified resource. (This is the point which should be/contain a failure, due to the mismatch in version.)
Expected behavior
Rather than a success response with modified resource, I expect that the interaction which specifies an update with a non-matching ifMatch version specified will result in response following the FHIR batch processing rules or FHIR transaction processing rules, as applicable for the request's Bundle.
Screenshot
Debugger view showing a Bundle received by a Spark FHIR server which bears a conditional update intended to be processed only if the resource's version is 1:

Spark version
Operating system + Database
- OS: Linux and Windows tested
- Database: MongoDB
Container service / Cloud infrastructure:
- Container service: Docker and AWS ECS tested
- Cloud provider: Local and AWS tested
- Cloud infrastructure: Containers
- Database as a service: local MongoDB and AWS DocumentDB with Mongo API tested
Additional context
As an additional test, I also modified a Spark server [HttpPost] Task<FhirResponse> Transaction(Bundle bundle) method to specifically iterate through all Bundle entries and change their embedded ifMatch value from a weak ETag to the unaffixed version id (using the same trimming RegEx mentioned in #713 ) prior to submitting the API request's Bundle to IFhirService.TransactionAsync(). (To verify that the weak ETag prefix and suffix weren't causing the issue.) That made no change, so I suspect (but have not verified) that the ifMatches requirement is being ignored, rather than misinterpreted, in transactions.
Describe the bug
When a
Bundleis submitted toIFhirService.TransactionAsynchavingPUT(update) entries bearing anifMatchrequirement in theirRequestComponent, the updates are processed irrespective of the target resources' version.As a result, this invisibly enables lost updates during transactions, which the
ifMatchrequirement seeks to avoid.To Reproduce
Steps to reproduce the behavior:
Using
Hl7.Fhir.R4NuGet package...FhirClient's endpoint. (e.g.,new TransactionBuilder(fhirClient.Endpoint, BundleType.Transaction))..Update()method. You must include aversionIdmanually to ensure theifMatchheader is included. (e.g.,transactionBuilder.Update(resource, "not-the-real-resource-version")). Note that the version specified must vary from the server's version in order to properly test this bug.Bundlefrom theTransactionBuilder(transactionBuilder.ToBundle()). (You should be able to verify the entry header by examining the resultingbundle.Entry[].Request.IfMatchproperty—which should have a value containing a weak ETag equivalent of the non-matching version specified in step 5.)fhirClient.TransactionAsync()).Expected behavior
Rather than a success response with modified resource, I expect that the interaction which specifies an update with a non-matching
ifMatchversion specified will result in response following the FHIR batch processing rules or FHIR transaction processing rules, as applicable for the request'sBundle.Screenshot
Debugger view showing a
Bundlereceived by a Spark FHIR server which bears a conditional update intended to be processed only if the resource's version is1:Spark version
2.1.0Operating system + Database
Container service / Cloud infrastructure:
Additional context
As an additional test, I also modified a Spark server
[HttpPost] Task<FhirResponse> Transaction(Bundle bundle)method to specifically iterate through allBundleentries and change their embeddedifMatchvalue from a weak ETag to the unaffixed version id (using the same trimming RegEx mentioned in #713 ) prior to submitting the API request'sBundletoIFhirService.TransactionAsync(). (To verify that the weak ETag prefix and suffix weren't causing the issue.) That made no change, so I suspect (but have not verified) that theifMatchesrequirement is being ignored, rather than misinterpreted, in transactions.