Featured

Recent Posts


Something went wrong. Please refresh the page and/or try again.

Advertisements

Troubleshooting Hidden Dependency Errors in Dynamics 365 and Dataverse


Recently, while cleaning up some old customizations in Dynamics 365, we came across an interesting dependency issue that was not immediately obvious from the user interface. What initially looked like a simple Business Process Flow deletion turned into a deeper investigation into how Dataverse manages published dependencies internally.

While trying to delete a BPF, Dataverse returned the following error: – Failed to delete (). Object dependencies exist, please review before deleting.

Normally, the first step in this situation is to use the built-in dependency viewer. However, in this case, the dependency screen itself was not particularly helpful. Even though the platform clearly stated that dependencies existed, the dependency dialog was not showing any actual records / components blocking the deletion.

To investigate further, we opened the browser developer tools and inspected the network response generated during the delete operation. The response payload contained much more detail than what was shown in the UI, including the GUID of the component and information indicating that dependencies still existed behind the scenes.

The Entity(99980477-1249-447b-8514-6d11fe6f1b1e) component cannot be deleted because it is referenced by 7 other components.

{“error”:{“code”:”0x8004f01f”,”message”:”The Entity(99980477-1249-447b-8514-6d11fe6f1b1e) component cannot be deleted because it is referenced by 7 other components. For a list of referenced components, use the RetrieveDependenciesForDeleteRequest.”}}

–changesetresponse_aa58f311-830f-4c7f-af82-f21732502a1e–

–batchresponse_26fe11bd-bb7c-4cef-ad4b-91121ac828cf—

With the component GUID available, we switched to SQL 4 CDS to query the dependency table directly. The following query was used:

SELECT *

FROM dependency

WHERE requiredcomponentobjectid = ‘99980477-1249-447b-8514-6d11fe6f1b1e’

The results immediately started revealing useful information. One of the most important columns in the results was:

dependencytype = 2, dependencytypename = Published

This turned out to be the key detail. A dependency type of Published means the reference is actively present in the environment and is currently preventing deletion of the component.

The dependency records also showed the following values:

dependentcomponenttype = 29, dependentcomponenttypename = Workflow

That told us the blocking component was actually a workflow. To identify the workflow names, we queried the workflow table directly using the workflow IDs returned by the dependency query, which took us to the below Workflow. When we opened this workflow, we found that it still contained a step creating or referencing the process we were attempting to remove.

We removed the workflow referencing the process, published the changes, and then retried the deletion. Once the workflow dependency was removed, the process was deleted successfully without any further errors.

This was a useful reminder that the dependency viewer in Dynamics 365 and Dataverse does not always surface every dependency clearly, especially with older workflows and process-related customizations. In these situations, SQL 4 CDS and direct dependency table queries can be extremely valuable for identifying hidden references.

Hope this helps..

Advertisements

Capture UTM Parameters in Dynamics 365 Marketing Forms Using JavaScript (Dynamics 365 Customer Insights)


When running marketing campaigns, UTM parameters help us understand where our leads are coming from. They help us track whether a lead came from Google Ads, Facebook campaigns, email campaigns, or some other source.

Recently while working with a Dynamics 365 Marketing form, we used a small JavaScript snippet to automatically capture UTM parameters from the URL and store them directly into marketing form fields.

 <script>
document.addEventListener("d365mkt-afterformload", function () {
    const params = new URLSearchParams(window.location.search);
      const mappings = [
        { param: "utm_source", name: "custom_utm_source" },
        { param: "utm_medium", name: "custom_utm_medium" },
        { param: "utm_campaign", name: "custom_utm_campaign" },
        { param: "utm_term", name: "custom_utm_term" },
        { param: "utm_content", name: "custom_utm_content" },
        { param: "gclid", name: "custom_gclid" },
        { param: "gclsrc", name: "custom_gclsrc" },
        { param: "fbclid", name: "custom_fbclid" }
    ];
    mappings.forEach(function (m) {
        const field = document.querySelector(`[name="${m.name}"]`);
        const value = params.get(m.param);

        if (field && value) {
            field.value = value;        
        }
    });
});
</script>

Suppose the marketing form URL is opened like this:

https://contoso.com/form?utm_source=google&utm_medium=cpc

In the example below, the values from the URL are automatically populated into the form fields.

The script first waits for the Dynamics 365 Marketing form to fully load using the d365mkt-afterformload event. This is important because the fields may not yet exist when the page initially loads.

After that, the script reads the query string from the URL using URLSearchParams. So if the URL contains values like utm_source=google or utm_medium=cpc, those values become available to the script.

The mappings array is used to map URL parameters to marketing form fields. For example, utm_source maps to custom_utm_source and utm_medium maps to custom_utm_medium.

The script then loops through each mapping, finds the matching field inside the marketing form, and sets the value automatically.

Using this approach helps us capture campaign attribution data directly inside Dataverse during form submission

References –

https://paulinekolde.info/javascript-library-for-real-time-marketing-form-in-customer-insights

Extend Customer Insights – Journeys marketing forms using code

Hope it helps..

Advertisements

Hidden Required Fields Causing “Please ensure all required fields are filled out” Error While Disqualifying a Lead in Dynamics 365 / Dataverse


While working on a Lead Disqualification scenario in Dynamics 365, we ran into a strange issue.

When trying to Disqualify a Lead, Dynamics 365 was showing the generic error message:

“Please ensure all required fields are filled out and have valid info.”

Even more confusing, the form itself was not showing any missing required fields.

This is one of those classic “ghost validation” problems in Dynamics 365 where fields are being marked as required dynamically through JavaScript or Business Rules, even though they are not visible on the form. The message was generic and did not indicate which field was causing the validation failure.

Since the form was not highlighting any required fields, we suspected that some fields were being set as required dynamically in the background. To identify them, we executed the following JavaScript in the browser console.

(function () {
    var missingFields = [];
    var attributes = Xrm.Page.data.entity.attributes.get();
    attributes.forEach(function (attribute) {
        var requiredLevel = attribute.getRequiredLevel();
        var value = attribute.getValue();
        var isEmpty =
            value === null ||
            value === "" ||
            (Array.isArray(value) && value.length === 0);
        if (requiredLevel === "required" && isEmpty) {
            missingFields.push(attribute.getName());
        }
    });
    if (missingFields.length) {
        alert("Missing required fields: " + missingFields.join(", "));
    } else {
        alert("No missing required fields found.");
    }

})();

The script immediately showed the fields that were marked as required internally:

Even though these fields were not visible on the form, they were still configured as required dynamically somewhere in the background.

To fix it – we found and updated the JavaScript method that was setting those fields as required. This is the cleaner and recommended approach.

The other quick fix though not recommended is to reset the fields to non-required on OnLoad/ OnSave/ OnChange.

formContext.getAttribute("custom_enquirytype")
    .setRequiredLevel("none");
formContext.getAttribute("custom_decisionmaker")
    .setRequiredLevel("none");

Sometimes these generic validation popups in Dynamics 365 can be a bit tricky because the actual field causing the issue is not even visible on the form.

Running a quick console script like the one above helped us immediately identify which hidden fields were still marked as required and blocking the Disqualify action

Hope it helps..

Advertisements

Preserving ‘modifiedon’ During Data Migration in Dynamics 365 / Dataverse


We were working on a data migration requirement where we needed to preserve system fields like created on and modified on.

For Created On, things are straightforward. We can use the overriddencreatedon field, something we had already explored earlier here:

https://nishantrana.me/2018/10/16/using-overriddencreatedon-or-record-created-on-field-to-update-created-on-field-in-dynamics-365/

In this post, we focus on preserving the modifiedon value.

We started with a simple approach. We registered plugins on Pre-Create and Pre-Update and set the modifiedon field directly on the Target entity. This worked well for normal create and update scenarios.

Everything was working fine… until we started migrating appointment records in the completed state. On checking the plugin execution, we observed the following sequence:

Create -> Update

The pre-update plugin although firing was not updating the value of the modified on field. This was because we have Set State message firing after Update which overriding the modifiedon set in the pre create / update plugin.

So we thought of implementing a plugin on the SetState / SetStateDynamicEntity message which will trigger when they are marked as completed instead of Update. However, in the SetStateDynamicEntity message, we do not receive a Target entity. Instead, we get an EntityMoniker (EntityReference) along with State and Status values. Because of this, we cannot directly set modifiedon in a Pre-Operation plugin for SetStateDynamicEntity.

To handle this scenario, we implemented a small workaround. We created an additional dummy field (for example, new_triggerupdate). Then we registered a plugin on Post Operation of SetStateDynamicEntity and performed a simple update on this dummy field. This update triggered the Update message again, which in turn executed our pre-update plugin where we were setting the modifiedon value.

So the final execution flow became:

Create -> Update -> SetStateDynamicEntity -> Update

And in this final Update, the modifiedon value was set correctly.

After the migration was completed, we disabled or removed these plugins to avoid impacting normal system behavior.

This approach helped us handle all scenarios including create, update, and activities being marked as completed during migration.

The plugin code –

 public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            string message = context.MessageName;
            tracingService.Trace($"Message: {message}");         
            DateTime forcedDate = new DateTime(2022, 12, 25);

            // =========================
            // CREATE & UPDATE (Pre-Op)
            // =========================
            if (message == "Create" || message == "Update")
            {
                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity target)
                {
                    tracingService.Trace("Handling Create/Update");

                    // Direct override works ONLY in Pre-Operation
                    target["modifiedon"] = forcedDate;

                    tracingService.Trace("Modifiedon overridden in PreOperation.");
                }
            } 

            // =========================
            // SETSTATE (Post-Op)
            // =========================
            if (message == "SetState" || message == "SetStateDynamicEntity")
            {
                tracingService.Trace("Handling SetState");

                if (context.InputParameters.Contains("EntityMoniker"))
                {
                    EntityReference entityRef = (EntityReference)context.InputParameters["EntityMoniker"];

                    Entity updateEntity = new Entity(entityRef.LogicalName, entityRef.Id);

                    updateEntity["new_touchfield"] = forcedDate.ToLongDateString();

                    service.Update(updateEntity);

                    tracingService.Trace("Modifiedon updated via service.Update in SetState.");
                }
            }
        }

Hope it helps..

Advertisements

Reset / Restore the standard (OOTB) button in Dynamics 365 / Dataverse


We recently worked on a requirement where we customized an out-of-the-box ribbon button in Dynamics 365 — specifically, the Reactivate Lead button. We had renamed it to ‘Reactivate’ as part of an earlier customization.

Below is how the button appeared on the form after customization:

Later, we had a new requirement to hide this button completely and replace it with a custom ribbon button that implemented our own reactivation logic. However, when we tried to hide the button using Ribbon Workbench, we noticed that the Hide option was not available.

When we opened Ribbon Workbench and inspected the button, we observed that since the button was already customized, the standard options like Hide were no longer available.

While working within the same Ribbon Workbench session, we could see the ‘Uncustomize Button’ option.

However, an interesting behavior we observed is that once we closed or reopened the solution inside the Ribbon Workbench, the ‘Uncustomise Button’ option was no longer available. In that case, only the Delete option was visible.

This is expected behavior. Once an OOTB button is customized, it becomes part of the solution layer, and certain default actions like Hide are no longer directly available.

To fix this and restore the original behavior, we followed a simple approach.

We selected the customized button in Ribbon Workbench and chose the Uncustomize Button or Delete option. We then published the solution and reloaded it. Once the solution was reloaded, the button was restored to its original out-of-the-box state. And now, the Hide option was available again as expected.

This allowed us to properly hide the OOTB button and proceed with implementing our custom ribbon button.

We referred to the blog below, which helped confirm the approach: https://innovativeaj.wordpress.com/2020/09/29/bring-me-back-to-life-restoring-the-d365-ootb-button-to-default-version/

Hope it helps..

Advertisements

The Attribute with id does not exist — and Staged Metadata is still being processed (Dataverse / Dynamics 365 Issue)


Last week, we came across a strange issue while working with Dataverse metadata.

We had created a new attribute as part of our solution changes. Everything looked fine initially, and the attribute was created successfully without any errors. However, when we tried to delete that same attribute, we started getting an error saying that the attribute does not exist.

This was confusing for us because the attribute clearly existed and was visible in the system.

“The Attribute with ID doesnt not exist”

To validate further, we tried adding the same attribute to another solution. This time, we received a different error stating that the staged metadata for the attribute is still being processed.

The staged metadata for Attribute is still being processed, please wait before you can do any update/delete/retrieve operations.

At this point, it was clear that this was not a normal behavior. It felt like the attribute was stuck in an intermediate state where it was created but not fully available for operations.

We checked the Known Issues list in the Power Platform Admin Center and found a matching issue: https://admin.powerplatform.microsoft.com/knownissues/6269936

We applied the suggested fix mentioned there, but it did not work immediately for us. Instead of trying multiple workarounds, we decided to wait for some time and raised a support ticket.

After a couple of hours, we retried the same operations. This time, both deleting the attribute and adding it to another solution worked without any issues.

The key takeaway from this experience is simple.

If we encounter errors like: – Attribute does not exist (even though it does) – Staged metadata is still being processed

It is worth giving the system some time before trying again and/or raising a support ticket in parallel instead of wasting time trying different options to fix it.

Hope it helps..

Advertisements

Nishant Rana's Weblog

Everything related to Microsoft .NET Technology

Skip to content ↓