Works locally, doesn't work in browser - "when converting object to numerical form ... unable to convert NaN to a numbert"

URL of experiment: consequential [PsychoPy]
Source code: Michael DePass / consequential_h0_v2 · GitLab
Description of the problem:
The task runs fine locally. I made the task 100% from the Builder (used Code Components but didn’t touch the generated Python or Javascript, relied solely on AutoJS).
When I run the task in the browser, the task starts but when I click on the central fixation a box pops up with the following error: “when converting an object to its numerical form; unable to convert NaN to a number”. In the debug console there are a lot of warnings like: “WARN Rect._setAttribute psychojs-2024.2.4.js:955 | setting the value of attribute: size in PsychObject: right_stimulus_1 as : undefined”. Then, after these warning there’s the following error: ““FATAL … _GUI.dialog psychojs-2024.2.4.js:1201 | {“origin”:“util.toNumerical”,“context”:“when converting an object to its numerical form”,“error”:“unable to convert NaN to a number”}””

I’m aware of the crib sheet and I think I only used online-compliant components.

Any help would be greatly appreciated. Thanks so much!

Oh, this is a subtle one. The issue is in this line of code, which is in one of your early code components.

  m_bounds = [(Math.max(difficulty) / 2), (1 - (Math.max(difficulty) / 2))];

Basically, if you say “Math.max(array)”, what you get back is “Not a number” (NaN), and that’s what’s happening here. m_bounds is two NaNs and something else in the system tries to use it like a number, and you get this crash.

For various reasons, the correct syntax is:

  m_bounds = [(Math.max(...difficulty) / 2), (1 - (Math.max(...difficulty) / 2))];

The three dots “spread” the array into its constituent values, so max returns the expected (numerical) value.

1 Like

Thank you for the quick, insightful reply!

I changed the code by removing the calls to max() and just used indexing instead. That being said, what is the most PsychoPythonic way to go about this? To manually edit the Javascript and maintain two versions of the code? From reading the docs I thought Python standard library functions like max and min would be supported by AutoJS.

You can switch a code component from “Auto->JS” to “Both” and it will keep the already auto-generated code, but you can now edit the JS separately (but it won’t update if you change the python). That setting is component-specific, so you should only need to do it for the one with the Math.max function.

Long-term, @jon and the dev team might need to update the auto->JS system to insert the spread operator for max and min functions when you pass them an array as an argument.

1 Like

Yeah, I was aware of the “Both” option but I was hoping to stick with Python as that’s what I’m familiar with. I’ll just avoid min/max for now. After removing min/max calls, I still get the same error as before. What I really need to do is learn how to debug Javascript. So I just skimmed the js console tutorial (Thomas Pronk / tutorial_js_console_log · GitLab). Is there a way to see the line number in the [experiment_name].js file where the error occurred? That would make it much easier to then add print statements in the right places. Pardon my ignorance, and thanks again for the replies.

Regrettably, no. It is one of the more annoying things about JS, if the error comes from a function in one of the libraries, it doesn’t give you the full stack trace up to the line in the experiment script that called the function from the library.

The repository hasn’t been updated so if you’re testing on Pavlovia you should update the experiment first. If you’re testing in a local browser, it might also be using cached code, so you might want to use an incognito tab with the local test if you can.

That said, if this is really the same error message, then the basic problem is the same: There is an operation in your code that is returning NaN when it should return an actual number, and then something tries to parse it as a number. If you pass an array as an argument to any Math function without the spread operator that can happen, but since I can’t see the updated code in the repository I can’t tell where it would be coming from if you took out the Math.max call.

1 Like