Bug: Branched Business Process Flow

Branched Business Process Flow was introduced in CRM 2015. I encountered a bug in BPF today, which took a day and a half to figure out. I am posting the scenario so that it will be beneficial for others who experience the same error. The bug is this:

When a lead is qualified an exception is thrown when:

  1. BPF has branches AND
  2. BPF has condition stages AND
  3. Some condition stages have only one output i.e only Yes or No
  4. Data in the form could lead to a condition block that will result in a dead end

This is the BPF, I created to test this bug.

Test BPF.png

As you can see I have a condition called “Existing account is not null”, and a stage if is true, not no stage if it is false. With this BPF an exception is thrown when the lead is qualified and Existing account is null. Below is the full error in Dynamics 365 Online.

lead-qualify-error

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
	<s:Body>
		<s:Fault>
			<faultcode>s:Client</faultcode>
			<faultstring xml:lang="en-US">An unexpected error occurred.</faultstring>
			<detail>
				<OrganizationServiceFault xmlns="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
					<ActivityId>8cf5f7f2-d08f-4e2d-9374-daf02247e5d0</ActivityId>
					<ErrorCode>-2147220970</ErrorCode>
					<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
					<Message>An unexpected error occurred.</Message>
					<Timestamp>2017-02-09T06:30:37.8410512Z</Timestamp>
					<ExceptionSource i:nil="true"/>
					<InnerFault>
						<ActivityId>8cf5f7f2-d08f-4e2d-9374-daf02247e5d0</ActivityId>
						<ErrorCode>-2147220970</ErrorCode>
						<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
						<Message>System.ArgumentNullException: Value cannot be null.
Parameter name: g</Message>
						<Timestamp>2017-02-09T06:30:37.8410512Z</Timestamp>
						<ExceptionSource i:nil="true"/>
						<InnerFault i:nil="true"/>
						<OriginalException i:nil="true"/>
						<TraceText i:nil="true"/>
					</InnerFault>
					<OriginalException i:nil="true"/>
					<TraceText i:nil="true"/>
				</OrganizationServiceFault>
			</detail>
		</s:Fault>
	</s:Body>
</s:Envelope>

This is the exception detail in CRM 2015.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
	<s:Body>
		<s:Fault>
			<faultcode>s:Client</faultcode>
			<faultstring xml:lang="en-AU">An unexpected error occurred.</faultstring>
			<detail>
				<OrganizationServiceFault xmlns="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
					<ErrorCode>-2147220970</ErrorCode>
					<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
						<KeyValuePairOfstringanyType>
							<a:key>CallStack</a:key>
							<a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">   at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.PipelineInstrumentationHelper.Execute(Boolean instrumentationEnabled, String stopwatchName, ExecuteWithInstrumentation action)
   at Microsoft.Crm.Extensibility.Pipeline.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.MessageProcessor.&lt;&gt;c__DisplayClass1.&lt;RunStage&gt;b__0()
   at Microsoft.Crm.Extensibility.PipelineInstrumentationHelper.Execute(Boolean instrumentationEnabled, String stopwatchName, ExecuteWithInstrumentation action)
   at Microsoft.Crm.Extensibility.MessageProcessor.RunStage(PipelineExecutionContext context, Int32 pipelineStage)
   at Microsoft.Crm.Extensibility.MessageProcessor.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.InternalMessageDispatcher.Execute(PipelineExecutionContext context)
   at Microsoft.Crm.Extensibility.ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequestRequestWithInstrumentation(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode, Object operation)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)
   at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)</a:value>
						</KeyValuePairOfstringanyType>
					</ErrorDetails>
					<Message>An unexpected error occurred.</Message>
					<Timestamp>2017-02-08T05:33:31.5174084Z</Timestamp>
					<InnerFault>
						<ErrorCode>-2147220970</ErrorCode>
						<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
							<KeyValuePairOfstringanyType>
								<a:key>CallStack</a:key>
								<a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/XMLSchema">   at System.Guid..ctor(String g)
   at Microsoft.Crm.ObjectModel.BusinessProcess.WorkflowConditionNextStageEvaluator.GetNextStage(StageStep stage)
   at Microsoft.Crm.ObjectModel.BusinessProcess.ActivePathEnumerator.MoveNext()
   at Microsoft.Crm.ObjectModel.BusinessProcess.ActivePathCalculator.Calculate(String targetEntityName)
   at Microsoft.Crm.Common.ObjectModel.NextProcessStageInformationFinder.CalculateGlobalStageAndTraversedInformation(String firstEntityName, String nextEntityName)
   at Microsoft.Crm.Common.ObjectModel.LeadService.QualifyLead(BusinessEntityMoniker leadId, Boolean createAccount, Boolean createContact, Boolean createOpportunity, BusinessEntityMoniker opportunityCurrencyId, BusinessEntityMoniker opportunityCustomerId, BusinessEntityMoniker sourceCampaignId, Int32 statusCode, ExecutionContext context)</a:value>
							</KeyValuePairOfstringanyType>
						</ErrorDetails>
						<Message>System.ArgumentNullException: Value cannot be null.
Parameter name: g</Message>
						<Timestamp>2017-02-08T05:33:31.5174084Z</Timestamp>
						<InnerFault i:nil="true"/>
						<TraceText i:nil="true"/>
					</InnerFault>
					<TraceText i:nil="true"/>
				</OrganizationServiceFault>
			</detail>
		</s:Fault>
	</s:Body>
</s:Envelope>

The root cause for this seems to be GetNextStage. It seems the method can’t figure out what the next stage should be, when the BPF ends with a condition with only one branch. I haven’t tested other scenarios where this error could be triggered, but I was able to consistently reproduce the error on lead qualify.

Unrelated Note:

It seems business process has a client side caching mechanism. I had to clear cache every time after I made change to the BPF to test this issue.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s