An unexpected method call was detected in the ConfigureHowToFindSaga

I’m running NServiceBus 7.4.4 and NServiceBus.Persistence.Sql 6.1.1

When I have two messages mapped in ‘ConfigureHowToFindSaga’ I receive the following error:

Unable to determine Saga correlation property because an unexpected method call was detected in the ConfigureHowToFindSaga method.

So, this compiles:

protected override void ConfigureHowToFindSaga(SagaPropertyMapper<MySagaData> mapper)
        {
            mapper.MapSaga(saga => saga.MyId)
                .ToMessage<Message1>(msg => msg.MyId);
        }

This doesn’t:

protected override void ConfigureHowToFindSaga(SagaPropertyMapper<MySagaData> mapper)
        {
            mapper.MapSaga(saga => saga.MyId)
                .ToMessage<Message1>(msg => msg.MyId)
                .ToMessage<Message2>(msg => msg.MyId);
        }

What am I doing wrong?

Could this be a bug in InstructionAnalyzer?

In method CallUnexpectedMethods the following code is executed:

		var badCalls = interestingCalls
		.Where(item => !item.IsConfigureMapping && !item.IsToSaga)
		.Where(item => !(item.IsExpressionCall && item.ExpressionCallsAllowed.Value))
		.ToArray();

When changing this to the following code, everything works:

		var badCalls = interestingCalls
		.Where(item => !item.IsConfigureMapping && !item.IsToSaga)
		.Where(item => item.IsExpressionCall && item.ExpressionCallsAllowed == false)
		.ToArray();

Hey @Bjorn,

I was prepared to admit that SQL Persistence had a bug, because this is our only test for that style of saga mapping and it only includes one ToMessage call:

However, I copied and pasted your code and built the saga around it and it compiled just fine, and the script was generated with the correct correlation id MyId.

Is it possible you have an IL-level AOP tool like Fody or PostSharp that is adding additional IL to the method?

If not, I would love to see a minimal repro - is it possible to create one? If you could send the repro to support and flag my name, we could probably get a test case added for that exact scenario and then get to the bottom of it.

As a workaround, you can probably do the older style of saga mapping:

mapper.ConfigureMapping<Message1>(msg => msg.MyId).ToSaga(saga => saga.MyId);
mapper.ConfigureMapping<Message2>(msg => msg.MyId).ToSaga(saga => saga.MyId);

Hello David,

I will prepare a repo first thing tomorrow. I can already confirm that the old style exhibits the same problem. The moment I put in the second line, the compilation error is there.

I’m not using Fody or Postsharp or any such tool.

Hello David,

I have sent the minimal repo in a support ticket. It is case ID#00063090.

Thanks

The problem is right here…the mapped property from the message is implemented as a field instead of a property. What’s happening is that the field access is creating different-enough IL that the IL interpreter we wrote to determine the correlation ID thinks you’re calling off into a different method (which is incorrect) because if you were, you could be doing all sorts of things to the mapping from that external method that we wouldn’t be able to observe from the IL.

I’ve raised a bug for this, which includes details on the IL involved if you’re interested. Whether or not fields are OK in messages has more to do with your choice of serializer than anything else, but the SQL script generation certainly shouldn’t fail because of it.

This is probably pretty low priority though and likely won’t get handled until swept up with other low-priority bugs into a maintenance release. The obvious workaround is to not use fields and use a property instead.

@DavidBoike This issue is still happening with the new version 8 beta-2. It was working just fine with version 7, but I now have this issue with version 8. The saga data is fine all using properties and I used both the new and old way to configure the saga.

These are the packages we’re using:

<PackageReference Include="NServiceBus.Persistence.Sql" Version="7.0.0-beta.2" />
<PackageReference Include="NServiceBus.RabbitMQ" Version="8.0.0-beta.1" />
<PackageReference Include="NServiceBus.Heartbeat" Version="4.0.0-beta.2" />
<PackageReference Include="NServiceBus.Metrics.ServiceControl" Version="4.0.0-beta.2" />
<PackageReference Include="NServiceBus" Version="8.0.0-beta.3" />
<PackageReference Include="NServiceBus.Extensions.DependencyInjection" Version="2.0.0-beta.2" />
<PackageReference Include="NServiceBus.Extensions.Logging" Version="2.0.0-beta.2" />

public class ProcessTelemetryFileSagaData : ContainSagaData
{
    public Guid TrackingId { get; set; }
}

protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper)
{
mapper.MapSaga(x => x.TrackingId)
.ToMessage(x => x.TrackingId)
.ToMessage(x => x.TrackingId);
}

Is this a known issues with the v8 beta?

Many thanks

We did not fix the bug I mentioned so I would actually be more surprised to hear that it works in V7 than to hear it’s not working in V8, as I would expect it to not work in both.

The specific problem is having a .ToMessage(…) expression point to a field. The simple workaround is to change message type to use properties instead.

@DavidBoike TrackingId is a property not a field. When are you guys planning on releasing a fix for this?

Thanks

@Marco_Encarnacao I’m really confused. This entire thread is about an error captured in the issue Saga script generation fails if message mapping maps to a field, so if you are saying that you are not using fields in your message mappings, and that “this” is still happening, then we must be talking about different definitions of “this”. :wink:

I would need to see the exact error you are getting and, in all likelihood, the complete code that’s causing it, which would mean the saga, the saga data, and the messages involved. If you’re not comfortable sharing that in a public forum, I would suggest you raise a support case.

@DavidBoike Sorry, the OP is mapping to a field, but I’m not, I’m mapping to properties and still get the same issue. The sql scripts are still generated tho.

Interesting, it’s probably a different issue then, even if it presents similarly. I would probably need to see a small repro to figure it out, as it could be a combination of the SQL Persistence instruction analyzer and/or the Roslyn analyzers for sagas that were added in NServiceBus 7.7 that could be involved.