Troubleshoot form issues in model-driven apps

This article has information to help fix some of the common issues you might encounter while working with model-driven app forms.

Important

  • The tools described in this article are designed for troubleshooting purposes; they aren't meant to be used in day-to-day production scenarios, even though you can use them for troubleshooting issues in production environments.
  • These troubleshooting tools only affect the current user session unless otherwise noted (for example, when a browser tab accesses the model-driven app). They don't change system customizations or affect any other users or sessions. After the current session is closed, the effect is no longer applied.
  • Most of the tools are available in all the production environments. Some of them mentioned in the article might not have been deployed to your organization yet; new tools are added periodically.
  • Tools listed in this article are written in a scenario-driven way. You can use them independently to troubleshoot different types of issues.
  • Use URL parameters to disable various form components and View registered form event handlers and libraries in Monitor are critical and fundamental tools you'll frequently use to troubleshoot many scenarios.
  • For more information on how to use Monitor, see Use Monitor to troubleshoot model-driven app form behavior

Use URL parameters to disable various form components

When you're troubleshooting issues with forms, you need to use the URL parameters to disable components as you work to isolate the specific component that caused the issue. We recommend that you use the flags one at a time to narrow down the cause of the issue. You can use the following URL parameters:

  • DisableFormCommandbar

    Disables the command bar on the form. It only disables the command bar on form pages and not supports list (grid), dashboard, etc.

    https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableFormCommandbar=true
    
  • DisableFormHandlers

    Disables all the form handlers. If you use the DisableFormHandlers=true flag, it disables the following event handlers: OnLoad, OnSave, business rule, OnChange, and TabStateChange.

    To learn more about obtaining event or library indices for granular controls, see View registered form event handlers and libraries in monitor.

    https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableFormHandlers=true
    
    • &flags=DisableFormHandlers=eventName

      Disables the form handler by specifying the event name, for example, **DisableFormHandlers=onload.

      https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableFormHandlers=true
      
    • &flags=DisableFormHandlers=eventName_index

      Disables the event handler at the specified index for any supported event name. For example, DisableFormHandlers=true_0 disables all the event handlers at index 0. DisableFormHandlers=onload_2 disables the OnLoad event handler at index 2.

    • &flags=DisableFormHandlers=eventName_startIndex_endIndex

      Disables all the event handlers within the given range by specifying startIndex and endIndex values (both are included). For example, DisableFormHandlers=true_0_2 disables all the event handlers of index 0, 1, and 2. DisableFormHandlers=onload_2_5 disables the OnLoad event handler of index 2, 3, 4, and 5. If you have more event handlers, you can use this approach to narrow down problematic handlers quickly.

    Note

    Business rules are authored in the business rule designer, compiled into the client-side script, and registered in multiple form events, such as OnLoad, OnSave, and OnChange. The way to disable business rules are very similar to other form events. However, there're a few key differences:

    • When you use DisableFormHandlers=true, businessrule, businessrule_*index*, or businessrule_*startIndex_endIndex*, you're disabling the business rule(s) in all the form events they're registered to.
    • For example, the following image shows instructions on refreshing business rule(s) in the backend. You only need to do it once in your organization, and you can revert your changes after troubleshooting.
      Refresh business rules
    • After you perform the above action and refresh the form, you'll see different message with additional information, as shown in the following image:
      Business rules individual control
  • DisableFormLibraries

    Disables form libraries and prevents the libraries from being loaded. To learn more about obtaining event or library indices for granular controls, see View registered form event handlers and libraries in monitor . The usage is similar to DisableFormHandlers, except it doesn't take an event name as the value.

    • &flags=DisableFormLibraries=true: Disable all the form libraries.
    • &flags=DisableFormLibraries=index: Disable form libraries at the specified index.
    • &flags=DisableFormLibraries=startIndex_endIndex: Disable form libraries in the range of startIndex and endIndex (both included).
  • DisableWebResourceControls

    Disables all the web resource controls on the form.

    https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableWebResourceControls=true
    

    Disable web resource

  • DisableFormControl

    Disables a form control. Specify the control name to disable the control. If you see that the issue goes away with &flags=DisableWebResourceControls=true, and there's more than one web resource control on the form, you can use this flag to further identify the control that's causing the issue.

    https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableFormControl=controlname
    
  • DisableBusinessProcessFlow

    Disables all the business process flows on the form.

    https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableBusinessProcessFlow=true
    
  • navbar This isn't a flag parameter; instead, use navbar=off in the URL.

You can also add multiple URL parameters separated with a comma (,).

https://myorg.crm.dynamics.crm/main.aspx?appid=00000000-0000-0000-0000-000000000000&pagetype=entityrecord&id=00000000-0000-0000-0000-000000000000**&flags=DisableFormHandlers=true,DisableWebResourceControls=true,DisableFormCommandbar=true,DisableBusinessProcessFlow=true&navbar=off

Note

The difference between DisableFormHandlers and DisableFormLibraries are:

  • The DisableFormHandlers flag disables form handlers regardless of the containing form libraries. In contrast, the DisableFormLibraries flag disables the form libraries (web resources) regardless of the functions (event handlers) included in the libraries. Simply put, DisableFormLibraries makes sure the specified JavaScript web resource files are not loaded.
  • The DisableFormHandlers flag doesn't prevent the containing form library from being loaded. Thus it doesn't stop the JavaScript code present in the library but not registered as an event handler from being executed. For example, if a form library new_myscript.js is written in the following way (not recommended practice):
  • You should start with DisableFormHandlers to see if the issue goes away, and if not, you can try DisableFormLibraries. Disabling any script always involves some risks of potentially breaking your form scenarios. However, the latter tend to have more side effects because of the disablement of the entire JavaScript files. Difference between DisableFormHandlers and DisableFormLibraries
  • Assuming the myOnloadHandler is registered as an OnLoad event handler, the DisableFormHandlers=true flag only prevents the second alert, whereas the DisableFormLibraries=true flag prevents both alerts.

View registered form event handlers and libraries in monitor

To view registered form event handles and libraries, you can view the FormEvents operation in Monitor.

Form events

You need the eventIndex and libraryIndex parameter values when using the DisableFormHandlers or DisableFormLibraries URL flags. After an event or library is disabled, you'll see the event enabled state in both FormEvents operation (an overall view of all registered event handlers of all events), and FormEvents.eventName operation (details logged when a specific event happens).

Form events OnLoad

Unexpected behaviors when loading a form

Some common issues that can cause unexpected behavior when a model-driven app form is loaded are:

  • Columns or controls don't have the values you expect.
  • Controls aren't disabled or aren't enabled.
  • Controls aren't shown or aren't hidden.

How to troubleshoot

There are multiple reasons why unexpected behaviors occur when a form opens. One of the most common is the OnLoad scripts that run synchronously or asynchronously to change the column or control behavior. To determine whether your script is causing the issue, you can disable the form handlers by appending &flags=DisableFormHandlers=true at the end of your app URL.

If the unexpected behavior stops occurring after you disabled the form handler, it's a strong indication that the specific form handler is causing this behavior. When you identify the script that's causing this behavior, follow up with the script owner to further troubleshoot this issue.

Saving in progress error message

Sometimes when you save a form, you see a Saving in Progress error message.

This error occurs when the form OnSave event is triggered before the previous OnSave event completes. This behavior isn't supported, and the error appears by design because calling the OnSave event before the previous OnSave event is complete causes recursive save loops with unintended consequences.

A typical cause for this error is the script that calls the save() method in the OnSave event handler. Another possible cause might be concurrent save() calls in the setTimeout() method, which might cause the error to intermittently show up, depending on whether the prior save() call was completed before another save() call was made.

How to troubleshoot

In Monitor, the FormEvents.onsave operation provides all the details that are causing the error (this call stack is modified for demonstration purposes). The call stack tells what exact web resource, function, line, and row number causing this error. The form checker can't detect the error if the issue can't be reproduced.

Save in progress error

Follow up with the script owner to further troubleshoot the issue.

Intermittent form errors

The most common cause of intermittent or random form errors is using unsupported client API methods. These errors have the following characteristics:

  • They occur only for specific records, users, regions, or browsers, or only during periods when the network or service load is high.
  • They rarely occur in support instances.
  • They might occur once on a computer, and the same error might occur again after you clear the browser cache.
  • formContext.getControl or formContext.getControl(arg).getAttribute() randomly returns null for a valid control or column.

There are many ways to write unsupported client API methods, and they all share a common pattern: they cause a race condition in the form load pipeline. Because they introduce a race condition, the issue only occurs when the custom script executes before the form is fully ready to be accessed via the client API. Many factors can cause a race condition:

  • In the JavaScript web resource, code is put into a global scope executes immediately when the web resource file is loaded, without waiting for the form to be accessible. Make sure the code is executed inside a valid form handler, such as an OnLoad handler.

    Unsupported Client API method

  • In the Power Apps component framework component script file, client API methods are accessed inside the init or updateView function. The init() and updateView() functions are executed immediately when the component is loaded, without waiting for the form to be readily accessible. You can't use unsupported Client API methods in Power Apps component framework components.

Client API is accessed inside a window.setTimeout() function in the web resource file. The page state is unpredictable when the setTimeout() method executes the wrapped function. Due to the nature of the timer function, when the execution occurs, the page might be in a transitional state (during page load or save) that's not readily accessible by the Client API.

How to troubleshoot

Using Monitor, you can access information that helps you determine when the unsupported client access occurred and when the access occurred at the wrong time due to a race condition. However, Form Checker doesn't report such unsupported client access when the unsupported code happens to execute at the right time that doesn't cause an issue.

Unsupported Client API

Note

The call stack has been modified for illustration purposes. The call stack shows details like web resource, function, and the line causing the error.

Follow up with the script owner to further troubleshoot the issue.

The form or record isn't saved when you try to save the form

A common cause is an OnSave event handler that calls the executionContext.getEventArgs().preventDefault() method to cancel the save operation.

How to troubleshoot

In Monitor, the FormEvents.onsave operation provides all the details of why the save event is canceled details than that are available from the form UI itself.

Record isn't saved error

Follow up with the script owner to further troubleshoot the issue.

Form freezes, loads slowly, or throws unexplained errors

There are many possible reasons for a form to freeze, load slowly, or throw a "Web resource method doesn't exist" script error or an error that isn't a common script error. Some of the possible reasons include:

  • Bad OnLoad scripts.
  • Web resource controls.
  • Ribbon button scripts and rules.
  • Synchronous network requests.
  • Custom plug-ins.
  • Business process flow errors.

How to troubleshoot

Determine if the issue reproduces without involving forms. If it does, then there's a broader issue that should be investigated out of the form's context. Actual ownership of the problem depends on the particular details case by case.

  • If you believe this issue only occurs on forms, see Use URL parameters to disable various form components to narrow down the component that's causing the issue.
  • If you identify that certain form libraries/script files caused the issue, follow up with the owner who made these customizations to find out the root cause of the issue.
  • If you identify that web resource controls cause the issue with the DisableWebResourceControls flag, then you can use the DisableFormControl flag to disable each one-by-one until the problem is longer reproduced. The last disabled control that doesn't reproduce the issue is the one that is causing the issue. Follow up with the owner of the control to further troubleshoot the issue.
  • If you identify that the issue is caused by the command bar/ribbon with the DisableFormCommandbar flag, it means this isn't an issue with the form but an issue with the command bar. Use Command Checker to troubleshoot individual commands and identify which one is causing the issue.

A business rule or custom script isn't working

This issue occurs if a business rule or custom script that used to work in the legacy web client stopped working in Unified Interface. One of the main reasons for this error to occur is when a business rule or script in Unified Interface references a control that isn't available in Unified Interface.

How to troubleshoot

One of the reasons that the business rule or script isn't working in Unified Interface is that the controls that are part of them don't exist in Unified Interface. Composite controls exist in the web client, but in Unified Interface composite control is broken down into parts and is stored differently. For example, if the column fullname is part of the business rule or custom script, columns firstname, middlename, or lastname should be used instead.

Once you launch form checker, you are able to see more details in the CompositeControl operation including the composite control that is causing the problem, the columns that can be used in the business rule or custom script instead and a full call stack (the call stack is modified for demonstration purposes).

Custom script not working

Follow up with the corresponding owner of the business rule or custom script to change the control suggested by the form checker.

Most forms have a Related tab. It opens the Related menu with Related menu items.

Related tab in a form, expanded

A Related menu item might not appear as expected.

How to troubleshoot

A related menu item might not appear because:

There should be a one-to-many or many-to-many relationship between the main table and the related table. A form shows a row from the main table. The related table is the one that should appear in the Related menu of the form. If these relationships don't exist, the related menu item doesn't appear.

To verify, go to the Power Apps portal, select Tables, and select the table that has the relationships you want to view.

The Related menu doesn't show related tables from certain relationships created by Dataverse. These relationships are marked as noncustomizable.

The AssociatedMenuConfiguration.IsCustomizable property indicates whether the relationship can be customized. The easiest way to check is by querying the relationship using Web API to view the AssociatedMenuConfiguration complex type data.

Suppose you want to check whether the relationship between the Business Unit and Goal tables is customizable. The SchemaName of this relationship is business_unit_goal. Enter this URL in your browser:

GET [Organization URI]/api/data/v9.2/RelationshipDefinitions(SchemaName='business_unit_goal')/Microsoft.Dynamics.CRM.OneToManyRelationshipMetadata?$select=AssociatedMenuConfiguration

You can also get the same data by querying the table definition:

GET [Organization URI]/api/data/v9.2/EntityDefinitions(LogicalName='businessunit')/OneToManyRelationships(SchemaName='business_unit_goal')/AssociatedMenuConfiguration

The response for either request might look like this:

{
    "@odata.context": "[Organization URI]/api/data/v9.2/$metadata#RelationshipDefinitions/Microsoft.Dynamics.CRM.OneToManyRelationshipMetadata(AssociatedMenuConfiguration)/$entity",
    "MetadataId": "2124b4bd-f013-df11-a16e-00155d7aa40d",
    "AssociatedMenuConfiguration": {
        "Behavior": "UseCollectionName",
        "Group": "Details",
        "Order": null,
        "IsCustomizable": false,
        "Icon": null,
        "ViewId": "00000000-0000-0000-0000-000000000000",
        "AvailableOffline": true,
        "MenuId": null,
        "QueryApi": null,
        "Label": {
            "LocalizedLabels": [],
            "UserLocalizedLabel": null
        }
    }
}

Observe that IsCustomizable is false. Therefore, the relationship isn't customizable and Goal doesn't appear in the Related menu.

If the table was created in Web Client (deprecated since 2019), it might not appear because it's disabled for Unified Client.

To verify, go to Solution explorer and select the table (entity). Ensure that Enable for Unified Client is checked.

Solution explorer shows that an entity isn't enabled for Unified Client

Tables created with the modern designer don't have this issue. They're always enabled for Unified Client.

Note

Certain system tables can't be enabled for Unified Client. For example, Process Session can't be used in model-driven apps.

Audit History isn't in the Related menu.

How to troubleshoot

Audit history isn't supported in these cases:

A Related menu item might appear when it shouldn't.

How to troubleshoot

A related menu item might appear because:

The system ignores form XML customizations for self-referencing many-to-many relationships. The system ignores these customizations because it isn't possible to indicate whether the customizations are for the primary table or the related table, which are both the same table in this case. Therefore, the system ignores these customizations.

If you modify the form XML to hide the related menu item, it still appears. Any form XML customizations for self-referencing relationships are ignored, like changing the order or the label of the related item.

Some system tables can't be hidden

For example, custom tables always show Activities related menu item. It isn't possible to hide it with the form designer or by modifying the form XML.

The text for related menu items aren't in the expected language.

How to troubleshoot

If some related menu items are displaying in a different language from the user's language, check whether the form XML is missing translated labels.

Check the form XML to see if there are labels defined for each language. For example, this form XML shows that the navContacts item only has a US English (1033) label: Contacts.

<NavBarByRelationshipItem Id="navContacts" Area="Sales" Sequence="10064" RelationshipName="contact_customer_accounts" Show="true">
  <Titles>
    <Title LCID="1033" Title="Contacts" />
  </Titles>
</NavBarByRelationshipItem>

To fix this issue, add the translated labels to the form XML. For example, this form XML shows that the navContacts item with both US English (1033) and German (1031) labels.

<NavBarByRelationshipItem Id="navContacts" Area="Sales" Sequence="10064" RelationshipName="contact_customer_accounts" Show="true">
  <Titles>
    <Title LCID="1033" Title="Contacts" />
    <Title LCID="1031" Title="Kontakte" />
  </Titles>
</NavBarByRelationshipItem>

If the text for the user's language isn't defined, the system uses the organization's base language. If that doesn't exist either, the system uses the US English text.

Why is a form showing or not showing in the form selector?

The form selector is a dropdown that allows users to switch between different forms for a particular table.

Expanded form selector, showing different forms available

You need to understand the conditions that control whether the form is displayed.

How to troubleshoot

A form is available in the selector when all of these conditions are met:

  1. User has permission to access the form.
  2. Form is added to the app module.
  3. Form isn't hidden with Client API.
  4. For Dynamics Customer Service workspace forms, ShowInFormSelector is set to True.

If a form isn't showing in the form selector,

  1. Check the affected user's security roles.
  2. Check if the form is added to the app module.
  3. Disable custom scripts.

Why an expected default form isn't shown by default?

When there are multiple forms for a table, the desired one isn't used as the default.

How to troubleshoot

The following criteria determine the first form shown to the user:

  1. If a formId is provided when opening a form, then that form is shown. A formId can be provided through Client API functions like openForm or in a URL.
  2. Otherwise, the most recent form that the user picked is shown. The system remembers the latest selection from the form selector.
  3. If the user hasn't used the form selector before, the system uses the form order.

If the form isn't available to the user, the system continues to find an appropriate form to show.

A form is available to the user when:

  1. User has permission to access the form.
  2. Form is added to the app module.

If no forms are available to the user, then the the fallback form is used.

Why a control is disabled/enabled or visible/hidden

There are many possible reasons why a control might be disabled or hidden when the form is loaded.

How to troubleshoot

You can use Monitor to view the FormControls operation that includes all the details about the initial control state when the form loads.

Forms controls check

Another place to check is the ControlStateChange.visible or ControlStateChange.disabled operation that explains why the control disable or visible state is changed at any time on the form. This operation explains the control state before the change, intended state change that might succeed, and the state after the change. Not all control state change attempts are successful. For a control disabled by form XML, you can enable it through client API in an OnLoad event handler. However, if control is disabled for security reasons, it's highly unlikely an attempt to enable it through client API would successfully change the state.

Control state changed

A control can be disabled by using the following list of rules in order. If a rule is met, then the following rules are ignored. If you want to change whether a control is disabled, you must change the input to the rule used for the result or to a rule earlier in the list.

  • If the flags DisableWebResourceControls=true or DisableFormControl=<control name> are passed and the control is affected by these flags, the control is disabled.
  • If the owning table is read-only in Unified Interface in table definitions, the control is disabled.
  • If the table isn't available in offline mode, the control is disabled.
  • If the current user doesn't have write permissions on the record, the control is disabled.
  • If the column definition has IsValidforCreate set to false, the control is disabled.
  • If the column definition has IsValidforUpdate set to false, the control is disabled.
  • If the current user doesn't have Assign to privilege, the owner column is disabled.
  • If the user doesn't have write permissions on the column defined by field-level security, the control is disabled.
  • If a client API script enables or disables the control, the control disabled state honors that setting.
  • If the control is disabled in the form designer, the control is disabled.
  • If the user doesn't have Append To privilege for the lookup control's table, or Append privilege on the current record's table, the lookup control is disabled

Finally, if the control passes all the above checks, the record state determines whether the control is disabled. The control is enabled by default on active records and disabled on inactive records.

Note

The difference between FormControls and ControlStateChange is that the FormControls operation reflects the initial control state when the form is loaded, while the ControlStateChangeoperation reflects the state change at any time on the form, whether it's during form load, in OnChange or OnSave events after the form is loaded.

Important

A control's disabled and hidden state can change multiple times when a form is first loaded. To know the reason why a control is hidden or disabled, make sure to check the last operation logged in the monitor. For example, if there are no ControlStateChange.visible/ControlStateChange.hidden operations for the control being investigated, the value and reasoning will be in the FormControls operation. Otherwise, it will be the value and reason in the last ControlStateChange.visible/ControlStateChange.hidden operation. You can order logs by timestamp to search for the last operation.

Why a control has a certain value on form load

A control might not have a specific value on form load as the user expected.

How to troubleshoot

There are many possible reasons why control can have a value when a form loads. The ControlDefaultValue operation in Monitor explains the source of the default values.

Default control value

If multiple updates are happening to a control's value, an Update Sequence indicates the final value. For example, here's a control with a default value and then overridden with a value passed with a client API script. There's a call stack provided.

Control value before

There are scenarios where columns are populated based on a relationship column mapping, in which case the event shows that.

Control value after

Verify where the value is coming from and take action based on the below table:

Source How to fix
Client API script Contact the script owner.
Default value Check the control's configuration.
Relationship column mapping Check the relationship configuration and update the column mapping.
Value passed by page input data passed via URL Check the API that opens the specific form with the issue, it's passing the value.

Why a tab or section is visible or hidden

There are many possible reasons why a tab or section might be hidden or visible.

How to troubleshoot

The TabStateChange or SectionStateChange operations in Monitor explain the visible state change, as shown in the following image. If a script causes it, then the call stack would reveal the web resource file, line number, and function name that caused this behavior.

Tab section

Follow up according to the suggestion in the state reason or the owner of the web resource/business rules to change or fix the behavior.

Unexpected dialogs or navigation

There are many possible reasons why a dialog appears, or navigation happens unexpectedly. One of the common causes is the Xrm.Navigation API methods are called to open a record or a form by a custom script. For example, when you open a form, an alert appears, as shown in the following image.

Alert dialog box

How to troubleshoot

The XrmNavigation operation in Monitor contains call stack that helps you identify the script that's causing unexpected behavior.

XrmNavigation operation in monitor

Follow up with the owner of the web resource to change or fix the behavior.

Opening another form instead of a quick create form

When opening a quick create form from a lookup or a grid, another form might open (edit or main form) instead of a quick create form. There are few reasons why this issue can happen:

  • The main form dialog force flag is being set.
  • Quick create form isn't available.

How to troubleshoot

You can use Monitor to view the FormType operation that includes all the reasons why a quick create form isn't opened.

Table not enabled for quick create

You need to follow up with the table owner who has disabled quick create through table definitions (metadata).

Table doesn't appear in the quick create menu flyout

When opening the global quick create menu flyout, not all tables are available. There are few reasons why the tables are filtered in this list:

  • There's no quick create form available for the table.
  • Table isn't enabled for quick create form.
  • Table isn't enabled for the new Unified Interface.
  • Table is read-only in Unified Interface.
  • Table's mobile client visibility can't be modified.
  • Table isn't part of the app module.
  • User doesn't have a create privilege on the table.
  • The create privilege isn't supported for the table.

How to troubleshoot

You can use Monitor to view the QuickCreateMenu operation, which includes all the tables and reasons why they're filtered from the quick create menu flyout.

See the following examples to understand the reasons for filtering. Based on the explanations, contact the responsible party or make changes accordingly.

Table not enabled for Unified Interface

Table not available for quick create

Table not part of app module

Unexpected unsaved changes message

When working on forms, you get the unsaved changes message on the form footer when you navigate from the current form or save the form without any changes.

How to troubleshoot

The unsaved changes error appears when you change the form and when the changes aren't saved. If you didn't make any changes manually, they could come from a JavaScript, plug-in, or business rule. You can use Monitor to view the UnsavedChanges operation that helps find the source of the changes. You can filter by OperationType UnsavedChanges.

The all attributes modified section includes a quick summary of the columns causing the unsaved changes error and their values. The unsaved changes section shows what happened to the columns in detail. For every column, you can see a list of controls that could be causing a change. The value change is also displayed (previousValue, newValue), and a call stack.

The following screenshot shows the root cause of the issue. You can see that the change came from the OnLoad script.

Unsaved changes error

Note

If the user has manually made the changes on the form, a call stack will not be provided.

Verify where the change is coming from and if the behavior is expected or not. If a script causes the change, the original web resource can be traced back in the call stack. In most cases, it's a script. Make a decision based on the web resource itself.

Business required column validation doesn't behave as expected

Business required columns by default block the form save operation if the value is empty. However, in many by-design scenarios, a business-required column might not block the save operation when the value is empty or block the save when you don't believe it should.

How to troubleshoot

The RequiredFieldValidation operation is logged when a save is attempted, regardless of whether save is successful or not. This operation explains why each business-required column blocks or doesn't block the save operation.

The following image is an example of this operation. The message explains how to read the detailed reports of each required column. In this example, fax column is bound to one control, and the control of the same name is read-only. Therefore it won't trigger required column validation.

Column validation

The following image is another example that jobtitle is a business-required column on the business process flow but not on the form, and the column isn't modified. Thus it doesn't block the save operation even when it's empty.

Required column validation

Follow up

Most times, the behavior is by design, and the RequiredFieldValidation operation explains why this column behaves in a certain way in form save operation. If the required column validation is skipped on a column because the control is disabled or hidden, as the first example illustrated, see the form checker suggestions for further analysis.

This might lead to another troubleshooting scenario such as Why a control is disabled/enabled or visible/hidden.

Some columns aren't displayed on the merge dialog

The merge dialog uses the default main form definition for the table and selectively renders most, but not all the columns in the dialog. This Form Checker operation explains why some of the columns aren't displayed on the merge dialog, even that they might be displayed on the main form.

How to troubleshoot

The following MergeDialog.load operation explains the reason why some columns aren't displayed.

In this example, parentcustomerid column on the contact form isn't supported in the merge dialog. The business card column isn't displayed because the containing section is hidden in the main form XML definition. Even though showing the owning section in the main form via client API is possible, the merge dialog honors the form XML configuration as event handlers aren't supported on the merge dialog.

Merge dialog load