When debugging the Bot Framework it is trivial to debug if you are developing in C#. It was bit of pain for me to do the same is node, as JavaScript is not my everyday language. But, after researching googling about this, I can say that it is really easy in node as well.

Now, to run the bot application in VSCode using Ctrl+F5 or typing “npm start” in the command prompt.

To debug the bot in Chrome DevTools, type “chrome://inspect/#devices“. Then click the “Open dedicated DevTools for Node” link. The page should be like this once you do this.

Chrome will now display the node application that it can detect in the Remote Target area. Click in the inspect link to open the DevTools. Now, set your breakpoint and use the emulator to send a message.

In the screenshot above you can see that I am already debugging using Chrome DevTools and debugger is waiting in the breakpoint that I set.

But, the user was indeed there from before and all I did was reactivate a long dormant user. My initial suspicion was that this had something to do with AD. I ran the following query to check the SID of the user against the MSCRM_CONFIG database:

If you decide not to use the CRM App for Outlook, syncing emails, contacts and appointments using just Server Side Sync and Forward Mailbox can be really painful sometimes, especially when you are troubleshooting why something is not being synced. The “Server-Side Synchronization Monitoring” Dashboard provides some assistance to the Administrator, but when you want to dig into the details, I often end up using “FetchXML Builder” or “LinqPad” to query the TraceLog entity. Below is the fetchxml I use

Another common scenario that I troubleshoot is, why an appointment is not synced to Outlook after it was created in CRM. The first thing to check in this case is the user’s sync filter. I use the XrmToolBox tool “Sync Filter Manager” to check what the user’s sync filter for appointment. After confirming that the fetchxml picks up the appointment that has to be synced, we can now proceed to stage 2 of troubleshooting.

The field that is key in this scenario is called “GlobalObjectId“. This field in the appointment entity will be set, after the appointment is synced to the user’s Outlook. Unfortunately, this field is marked as not searcheable, which means it cannot be used in Advanced Find.

But, we can still create view that shows the synced appointments and appointments that have not been synced, using FetchXML Builder. Below are the steps

Install FetchXML Builder from XrmToolBox store, if you don’t have it already

Save an existing view into a new view on appointment entity. Don’t worry about the filters yet as we will update this using FetchXML Builder

Next step is to open this view in FetchXML Builder

Update the fetchxml and save the view. Confirm the user’s sync filter for appointment using the Sync Filter Manager and make sure the new fetchxml criteria match with the user’s sync filter criteria

If you try to use the view from Advanced Find, you will get this error.

This means you have to use FetchXML Builder to update you fetchxml, if any changes are required in the future. If you want to add more columns to the view, you’ll have to use “View Designer” to do that, as you would not be able to use Advanced Find to do this, because of this error.

I hope this post will help you troubleshoot future appointment sync issues.

When you follow the “lift and shift” upgrade method i.e. backup the old CRM database, restore it in the target environment and run deployment manager to import the organisation database, upgrade should be relatively easy. But, recently I experienced an issue that was such a pain to troubleshoot, I thought I will share this experience so that it will be helpful to others.

Below is the error I got when I import the organisation database using Deployment Manager.

This is what is captured in the deployment manager log (%AppData%\Roaming\Microsoft\MSCRM\Logs)

It looks like the database server name is wrong. But it is not. I used “Process Monitor” to troubleshoot the error. Here is what “Process Monitor” picked up.

As you can see, the underlying error is a caused to lack of permissions to copy a dll file to a UNC path pointing to the database server.

Cause: McAfee Antivirus was blocking copy of any dlls through UNC path.

Resolution: Turn off “On Access Scanner” and “Access Protection” features of McAfee Antivirus during the organisation import.

In my case the KB article for SqlServerPathOverrides caused me to waste more time. I still had the same issue even after creating the network share, as McAfee was blocking all dll copy operations to UNC paths.

Today I discovered by accident, an useful setting in Office 365 App launcher. Here is how the Office 365 App launcher looks like

This UI is shown when you click the launcher icon next to “Dynamics 365”. You can set an URL to open when you click this icon, instead of navigating to the default “home.dynamics.com”. You do this by clicking the gear icon on the top right and choosing “Preferences”.

Once this is set, you can head straight to the normal CRM Dynamics 365 area, instead of “home.dynamics.com” when you click the Dynamics 365 icon in the launcher.

Business Rules is composed of two components: a client side JavaScript and a server side workflow. You can use these queries to find out the details about this:

LinqPad – Query and result

FetchXml Builder – Query and result

One gotcha with the business rule is that its behavior will deviate, if a field that is required by the business rule is removed on the form. I will demonstrate this, with the business rule below.

This business rule sets the “Contracting Unit” to required, if Order Type is “Work Based”. Below are the screenshots of the form in two different scenarios:

With “Order Type” present on the form

Without “Order Type” present on the form

As you can see, “Contracting Unit” is set to required, only if the “Order Type” field is present on the form, even if the value of “Order Type” is “Work based”. At present, there seems to no check in the form customisation area to prevent a field from being removed, if is required by a business rule. This is how the “Contracting Unit is required” business rule, gets translated into JavaScript.

When you debug this using Chrome Dev Tools, you can easily see why the “Contracting Unit” field is not being set to required.

To assist developers who are troubleshooting why a business rule is not working, I have developed this simple script to run in the DevTools console, that lists the fields that are required by the Business Rules, but are not present in the form. This has to be run in the context of ClientApiWrapper IFrame.

It is saying that “Order Type” should be present in the form, as it is required by a Business Rule that is running on the form. It uses an unsupported internal method to identify this information, and so I recommend that it be used in devtools console only.

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:

BPF has branches AND

BPF has condition stages AND

Some condition stages have only one output i.e only Yes or No

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.

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.

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.