Fixed – “Action cannot be performed. This quote is not owned by Dynamics 365 Sales” in Dataverse / Dynamics 365


Recently, while working with Quotes in Dynamics 365 Sales integrated with Supply Chain Management (SCM) through Dual-write, we encountered an interesting error while trying to activate an existing quote.

When attempting to activate Quote, the system threw the following error message:

Checking the Plugin Trace Log, we found the following details:

Entered Microsoft.Dynamics.SCMExtended.Plugins.QuotePreUpdate.Execute(), Correlation Id: 97636eb7-a10c-4503-918f-6dd7b8c1a671, Initiating User: 2953f4a9-ffca-ea11-a812-000d3a6aa8ae

QuoteService: PreUpdate.

Validate calling user $2953f4a9-ffca-ea11-a812-000d3a6aa8ae.

Calling user not DataIntegrator

Feature: Dynamics. AX.Application.SalesQuotationD365SalesFeature; Enabled: True

QuoteService: update from CE.

Validate calling user $2953f4a9-ffca-ea11-a812-000d3a6aa8ae.

Calling user not Dual-write.

SCM plugin exception: Action cannot be performed. This quote is not owned by Dynamics 365 Sales., at Microsoft.Dynamics.SCMExtended.Plugins.Services.QuoteService.ValidateIntegrationOwnerOnStateCodeChange(LocalPluginContext localContext, Guid quoteId)

Interestingly, this issue occurred only for old quote records — the ones created before Dual-write was enabled.

All newly created quotes after enabling Dual-write worked perfectly fine and could be activated without any error.

When comparing both sets of records, we noticed one key difference:

The msdyn_quotationownership (Ownership) field was blank for old quotes, while it was populated for the new ones.

This field plays an important role once Dual-write is enabled. The Microsoft.Dynamics.SCMExtended.Plugins.QuotePreUpdate plugin checks the Ownership field during operations like quote activation to validate the integration source.

If this field is empty, the plugin assumes the quote doesn’t belong to Dynamics 365 Sales and blocks the action, resulting in the error we saw.

Here we simply needed to set the missing ownership field.

A screenshot of a computer

AI-generated content may be incorrect.

To resolve the issue, we bulk updated all old quotes to set the missing Ownership (msdyn_quotationownership) field to Dynamics 365 Sales.

Once updated, the system immediately allowed us to activate quotes successfully — no more errors.

Hope it helps..

Advertisements

What are Partial Merges in Business Process Flow (BPF), and what can we do about it – Dataverse / Dynamics 365


Let’s take an example.

Suppose we have the following Business Process Flow (BPF) for Leads:

If the Lead Type = Grade A, we want the Grade A Details stage to appear. For other grades (B, C, D), we skip that stage and continue. So far, this is simple.

A screenshot of a computer

AI-generated content may be incorrect.

Now, say we have a new business requirement :

For Grade D, the process should only have the Initial Review and its own Closed stage. For Grades B and C, the process should follow Other Details + Closed.

To handle this, we added a condition:

If Lead Type = B or C → go to Other Details

Else (Grade D) → go directly to Grade D (Closed)

A computer screen shot of a computer

AI-generated content may be incorrect.

However, when we try to connect the B/C path to Other Details, the D path (Closed) also gets merged into it.

A screenshot of a computer
AI-generated content may be incorrect.
This is because of the way branching works in BPF.

Dataverse does not support “partial merges.” That means we can’t end one branch early and merge another branch later. If we merge one branch, Dataverse forces all branches to merge into the same stage.

A screenshot of a computer

AI-generated content may be incorrect.

One Branch Ends, One Branch Merges (Not Supported) – If we try to design a BPF where one branch terminates in its own last stage while the other continues and merges into a later stage, the platform will not allow it.

There are two ways to solve this:

Option 1: Repeat the stages : Instead of trying to merge one path and end another, duplicate the stages where needed.

For example, create a separate Other Details and Closed stage for Grades B and C.

A computer screen shot of a computer

AI-generated content may be incorrect.

Option 2: Simplify with fields / scripts

If we don’t want to repeat too many stages, we can:

Move the Lead Type field and Grade A Details fields into the Initial Review stage. Use business rules or form logic to show/hide those fields based on Lead Type. Delete the extra Grade A Details stage.

Update the condition so that the flow only needs one condition (A/B/C vs D).

A computer screen shot of a computer screen

AI-generated content may be incorrect.

Key Takeaway –

In Dataverse BPF:

One branch ending while another merges is not supported.

Either all branches merge or each branch must have its own end stage.

The solution is to repeat stages where needed, or simplify the design using fields and conditions.

Hope it helps..

Advertisements

Troubleshoot “Something happened, and we couldn’t copy to this environment” error – Dataverse /Dynamics 365 


Recently, while trying to copy an environment, we got the following issue –

Something happened, and we couldn’t copy to this environment. Please retry. If the issue continues, go to the Help + support tab. Include this correlation ID: 5e294f10-a784-4cda-881f-37799a37ddbc

At first glance, this seemed serious, especially because it mentioned a correlation ID and hinted at contacting Microsoft support.

In History also we can see it showing the status as failed.

A screenshot of a computer

AI-generated content may be incorrect.

We simply retried the copy operation — and this time, it worked flawlessly.

This indicates that the issue was likely transient, possibly caused by temporary backend resource availability or network hiccups.

Takeaway: Not every red error banner means a deep technical issue. Sometimes, it’s just the system asking for another try.

Hope it helps..

Advertisements

Fixed –Lookup value plugintypeexportkey [Guid] is not resolvable – Solution Import error (Dynamics 365 / Dataverse)


Recently, we faced an interesting import failure while moving a solution containing a Custom API.

Solution “Temp Plugin Step Custom API Transfer” failed to import: Lookup value 8f3269b7-a24d-43e4-9319-0c5e7ddf2b53 is not resolvable.

A screen shot of a computer

AI-generated content may be incorrect.

This clearly pointed to a lookup resolution issue — the solution import process was trying to bind the Custom API to a Plugin Type (class), but couldn’t find the referenced plugin in the target environment.

Each Custom API will have its own folder inside the Solution.

A screenshot of a computer

AI-generated content may be incorrect.

Looking into the solution files (specifically the customapi.xml) of that particular Custom API, we found this section:

A screenshot of a computer
AI-generated content may be incorrect.

Notice the <plugintypeexportkey> tag. This is where the Custom API references the Plugin Type (the actual C# class implementing the logic).

A computer screen with text and arrows pointing to it

AI-generated content may be incorrect.

When a Plugin class is created in Dynamics 365, it gets assigned a unique Plugin Type Id (GUID).

In the source environment, the Custom API was tied to a plugin with ID 420c7261-7461-4b37-87f0-1afcec427a46. However, in the destination environment, which was another development environment, a different plugin class was already created for that custom api. So during solution import, Dataverse tried to match the GUID 420c7261… but couldn’t find it in the target environment. Hence, the lookup resolution failed, and the solution import was blocked.

To resolve this, we manually updated the GUID in the customapi.xml to match the Plugin Type Id of the destination environment. Below, we are getting the ID from the Plugin Registration tool. The other option to fix would have been to remove the Plugin reference from the source, export, and then import.

A screenshot of a computer

AI-generated content may be incorrect.

After making this change, we re-imported the solution, and it worked successfully.

Also check – https://technicalcoe.com/2024/07/04/troubleshooting-power-platform-solution-import-errors/

Hope it helps..

Advertisements

Using addNotification to Simulate Dynamic Tooltips (Dataverse / Dynamics 365)


When working with forms in Dynamics 365 / Power Apps model-driven apps, we often customize field labels based on context, using the setLabel method. At times, we would also like to change the tool tip to go with the changed label of the field. The tooltip is defined as a Description of the field.

Below is the Topic (subject) field of the lead.

A screenshot of a computer

AI-generated content may be incorrect.

However, we cannot set the tool tip (description) of the field dynamically in the form using the Client API. So, what do we do when the meaning of a field changes depending on another value on the form? That’s where addNotification comes in as a handy workaround.

Let us take a simple example to see how we can use it. On the Lead form, the Topic(subject) field means different things depending on the Lead Source. So here we will be changing the label of the Topic (subject) field, along with setting a different notification message.

For e.g., if Lead Source – Advertisement, we are changing the label to Campaign Name. We can also notice the bulb icon next to the field.

A screenshot of a computer

AI-generated content may be incorrect.

Clicking on it, we can see our message –

A screenshot of a web page

AI-generated content may be incorrect.

Similarly, on changing the Lead Source to Web, we are changing the label to Landing Page, and clicking on the icon, we can see a different message.

A screenshot of a web page

AI-generated content may be incorrect.

Sample Code –

function updateSubjectField(executionContext) {
	
    var formContext = executionContext.getFormContext();
    var leadSourceAttr = formContext.getAttribute("leadsourcecode");
    var subjectControl = formContext.getControl("subject");
   
    subjectControl.clearNotification("subjectTooltip");

    var leadSource = leadSourceAttr ? leadSourceAttr.getValue() : null;

    if (leadSource === 1) { 
        // 1 = Advertisement
        subjectControl.setLabel("Campaign Name");
        subjectControl.addNotification({
            messages: ["Enter the name of the ad campaign"],
            notificationLevel: "RECOMMENDATION",
            uniqueId: "subjectTooltip"
        });
    }
    else if (leadSource === 2) { 
        // 2 = Referral
        subjectControl.setLabel("Referrer Notes");
        subjectControl.addNotification({
            messages: ["Mention details about the referrer"],
            notificationLevel: "RECOMMENDATION",
            uniqueId: "subjectTooltip"
        });
    }
    else if (leadSource === 8) { 
        // 3 = Web
        subjectControl.setLabel("Landing Page");
        subjectControl.addNotification({
            messages: ["Provide the landing page URL"],
            notificationLevel: "RECOMMENDATION",
            uniqueId: "subjectTooltip"
        });
    }
    else {
        // Default
        subjectControl.setLabel("Subject");
    }
}

While addNotification isn’t a perfect replacement for a native tooltip, it’s a practical workaround when we need dynamic, context-aware user guidance.

Hope it helps..

Advertisements

Clearing Dirty Fields in Forms to Avoid Unnecessary Save Prompts (Dynamics 365 / Dataverse)


In Dynamics 365 forms, we often run into situations where a record looks unsaved even though the user hasn’t made any manual changes. This usually happens when fields are updated in the background by scripts. When that happens, those attributes are flagged as dirty and the form behaves as if the user made edits. The result is that whenever users try to navigate away, they are interrupted by the familiar “You have unsaved changes” popup.

Also Check – https://nishantrana.me/2025/09/09/finding-dirty-unsaved-fields-on-the-form-using-javascript-browser-console-dynamics-365-dataverse/

In our case, we were getting this issue for fields which were already hidden from the form. Also here as the record was on a particular stage, where we were setting all the fields in the form read-only, and also cancelling the save event. Because of which user was also not able to save the form.

A computer screen shot of a computer program

AI-generated content may be incorrect.

The way we fixed this issue was to scan all the attributes on the form in onload, detect which ones are dirty and reset their submit behaviours. By setting their submit mode to “never“, these fields were not included in the save operation, and the form was now showing the saved state, thus no unsaved changes prompts.

clearAllDirtyFields: function (executionContext) {
    var formContext = executionContext.getFormContext();

    // Delay to allow system updates (rollups/calculated fields) to complete
    setTimeout(function () {
        formContext.data.entity.attributes.forEach(function (attr) {
            if (attr.getIsDirty()) {
                attr.setSubmitMode("never");
                console.log("Dirty flag cleared for: " + attr.getName());
            }
        });
        console.log("All dirty fields cleared from the form.");
    }, 3000); // adjust delay as needed
}

This approach should still be used with some caution. The best practice is to first understand why certain fields are showing as dirty and, if possible, fix the underlying cause. The script should only be used in specific situations where we are confident that the dirty fields are not needed for saving the record. It’s also important to add the right checks or conditions so that it doesn’t run everywhere unnecessarily.

For example, in our case we only applied it when the form was in a particular status where it was expected to be read-only for the user. The fields were already hidden, so letting them stay dirty served no purpose.

Hope it helps..

Advertisements