JavaScript web resources in Dynamics 365 are what you use when business rules and OOB functionality don’t quite get you there. Debugging them is how you figure out why your perfectly reasonable logic is being ignored by the form.
When you start writing more client-side scripting in Dynamics, you realize very quickly that the hard part usually is not the logic. The hard part is figuring out whether the code is firing at all, whether the form is loading old code, whether you used the wrong field name, or whether Dynamics is quietly humbling you for sport.
When to Use JavaScript Web Resource Debugging
Use the following debugging methods when:
- Your OnLoad / OnChange / OnSave logic isn’t firing
- Fields aren’t behaving the way your code says they should
- You’re staring at your screen thinking, this should work...
Do NOT use this when:
- A business rule can handle it
- The issue is configuration, not code
- The field is not on the form, the event is not registered, or the wrong function is being called
Sometimes the problem is not JavaScript. Sometimes it is just a missing form event and 45 minutes of your life you are never getting back.
Pre-flight Checklist (Before You Start Blaming JavaScript)
Before you debug anything, confirm:
- The web resource is published
- The JS file is added to the form
- The function is registered on the correct event
- You passed executionContext
- You are using logical names, not schema names
- You did a hard refresh (
Ctrl + F5) - You are testing the correct form and not some other version floating around in the app
Future You will thank you for checking this before going down a rabbit hole.
Step-by-Step (Test Small First)
1. Open the Console
Hit F12 and go to Console.
This is where you stop guessing and start knowing.
If your function is erroring, the console is usually the first place Dynamics will tell on itself.
2. Hard Refresh First
Use Ctrl + F5.
If you do not do this, you might be debugging old code and not even realize it.
Ask me how I know.
Caching is one of the biggest reasons people think their “new code” is broken when Dynamics is still running the old version.
3. Confirm the Function Is Actually Firing
Add a log at the top of your function:
console.log("Function is running");If you do not see it, your issue is probably not your logic.
It is usually one of these:
- The event is not registered
- The function name is wrong
- The web resource is not published
- The form is loading a different script than the one you think it is
Do not be a hero and debug line 40 before proving line 1 is running.
4. Check executionContext
This one gets everyone eventually.
var formContext = executionContext.getFormContext();If you did not pass executionContext in the form event handler, your function may fail quietly or throw an error depending on how the code is written.
This is one of the first things I check when something “looks right” but still refuses to work.
5. Log the Actual Field Values
Do not assume. Log.
var field = formContext.getAttribute("viz_fieldname");
console.log("Field value:", field ? field.getValue() : "field not found");This tells you two important things immediately:
- Whether the field was found at all
- What value Dynamics is actually returning
A shocking amount of debugging is just discovering that the value is not what you thought it was.
6. Test Directly in the Console
You can run commands manually in the browser console to isolate the problem.
For example:
Xrm.Page.getAttribute("viz_name").getValue();Or trigger your function directly:
YourNamespace.yourFunction(Xrm.Page);This helps you figure out whether the issue is:
- The function itself
- The form event registration
- The field name
- Or something else entirely
If the code works manually but not from the form event, the problem is almost always registration or event setup.
7. Use Breakpoints When You Are Done Guessing
Go to the Sources tab in browser dev tools, find your JS file, and click a line number to set a breakpoint.
Then trigger the event and step through the code.
This is where debugging actually becomes easier because you can watch values change in real time instead of making emotional guesses based on vibes.
Common Gotchas (The Stuff That Burns Consultants)
1. Function Not Firing
This is the classic.
Common causes:
- Event not registered
- Wrong function name
- Web resource not published
- Wrong library added to the form
- Function attached to the wrong column event
Before you rewrite your code, make sure the function is actually being called.
2. Logical Name vs. Schema Name
Everything in your JavaScript should use the logical name, typically lowercase.
"viz_businessunit" // ✅
"viz_BusinessUnit" // ❌This will absolutely ruin your day.
If a field “is not found,” this is one of the first things to check.
3. Multi-Select Choice Fields Return Arrays
This matters a lot when your logic depends on values being selected.
var values = field.getValue(); // [100000000]That is an array, not a single value.
So if you treat it like one value, your condition will fail and you will wonder why your logic is broken when it is technically doing exactly what you told it to do.
4. Attribute vs. Control Confusion
These are not the same thing.
getAttribute()= the datagetControl()= the UI element on the form
If you want to check or set a value, use the attribute.
If you want to show, hide, or disable something visually, use the control.
You usually need both at different points.
5. Code Runs Before the Form Is Ready
Sometimes something returns null not because your logic is wrong, but because the form or field is not ready yet.
This is especially painful when you are referencing tabs, sections, or controls that are not available the moment you expect them to be.
Add defensive checks. Do not assume everything exists just because it should.
6. Caching Lies to You
You updated the code.
You published the code.
You know the code is different.
And yet Dynamics is still acting like none of that happened.
Because it is still loading the old version.
Fixes:
Ctrl + F5- Republish the web resource
- Remove and re-add the library if needed
- Use a versioning habit in your deployment process
This is one of those issues that makes you question your own sanity for no reason.
7. Not Using a Namespace
Please do this.
var PPGirl = PPGirl || {};
PPGirl.Form = {
myFunction: function (executionContext) {
var formContext = executionContext.getFormContext();
console.log("Running function");
}
};Why this matters:
- Prevents naming conflicts
- Keeps your functions organized
- Makes it easier to debug and maintain later
- Avoids dumping random global functions everywhere like it is 2009
Consultant law #12: if it is not namespaced, it will break later, just not today.
Validation Checklist (How You Prove It Worked)
Before you move on, confirm:
- Console logs are showing
- No red errors appear in the console
- The function fires consistently
- The fields behave correctly
- You tested more than one scenario
- You tested both the happy path and the annoying path
- You confirmed the behavior after publish and refresh
Future You will thank you when this does not break in UAT.
Real Scenario: Required Field Logic That “Should Have Worked”
You write JavaScript to make a field required based on a choice value.
Simple enough.
Except it does not work.
So you check:
- The function is not firing because
executionContextwas not passed - You fix that
- Now the function fires, but the field still is not behaving correctly
- You log the field and find out the logical name is wrong
- You fix that
- It still looks broken
- You do
Ctrl + F5 - Suddenly everything works
You did not rewrite the logic.
You just debugged the setup correctly.
That is a very normal Dynamics JavaScript day.
Final Thought
JavaScript in Dynamics is not hard.
Debugging it without a system is.
Log everything.
Test small first.
Use a namespace.
Check the console before you start rewriting code that is probably innocent.
And seriously: do not be a hero and assume it is working without validating it.