Skip to content

ENH: improve FreeSurfer error message when executable not found#13790

Open
ayuclan wants to merge 22 commits intomne-tools:mainfrom
ayuclan:fix-freesurfer-error-message
Open

ENH: improve FreeSurfer error message when executable not found#13790
ayuclan wants to merge 22 commits intomne-tools:mainfrom
ayuclan:fix-freesurfer-error-message

Conversation

@ayuclan
Copy link
Copy Markdown

@ayuclan ayuclan commented Mar 26, 2026

Closes #12917

Improved error message when FreeSurfer executable (e.g., mri_watershed) cannot be found.

  • Clarifies need for proper FreeSurfer setup
  • Mentions adding $FREESURFER_HOME/bin to PATH
  • Notes that Python/Jupyter should be started from configured shell

This helps users diagnose common setup issues more easily.

@ayuclan ayuclan closed this Mar 26, 2026
@ayuclan ayuclan reopened this Mar 26, 2026
@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Mar 26, 2026

Hi, this is my first contribution to MNE.

I’ve added a clearer error message for missing FreeSurfer executables. I also saw pre-commit auto-fixes applied—please let me know if any further changes or formatting adjustments are needed.

Thanks!

@wmvanvliet
Copy link
Copy Markdown
Contributor

If we don't opt for some magic solution where MNE-Python tries to go the FreeSurfer setup itself, then this is indeed a much better error message. Thanks @ayuclan!

Comment thread mne/bem.py Outdated
Copy link
Copy Markdown

@JiwaniZakir JiwaniZakir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling in bem.py catches FileNotFoundError specifically for the mri_watershed executable, but the error message hardcodes that name rather than referencing the actual command from cmd[0]. If run_subprocess_env raises FileNotFoundError for a different reason — e.g., an input file path issue on some platforms — the message will be misleading. Consider either extracting the executable name dynamically (cmd[0]) or at minimum catching the exception as e and checking e.filename to verify it matches the expected executable before reraising with the custom message. Additionally, it's worth adding a test case that mocks run_subprocess_env to raise FileNotFoundError and asserts that the resulting RuntimeError message contains the expected guidance text, since this new branch is currently untested. The documentation link at the end of the message ("See MNE installation documentation for details.") would be more useful if it included an actual URL.

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Mar 30, 2026

The error handling in bem.py catches FileNotFoundError specifically for the mri_watershed executable, but the error message hardcodes that name rather than referencing the actual command from cmd[0]. If run_subprocess_env raises FileNotFoundError for a different reason — e.g., an input file path issue on some platforms — the message will be misleading. Consider either extracting the executable name dynamically (cmd[0]) or at minimum catching the exception as e and checking e.filename to verify it matches the expected executable before reraising with the custom message. Additionally, it's worth adding a test case that mocks run_subprocess_env to raise FileNotFoundError and asserts that the resulting RuntimeError message contains the expected guidance text, since this new branch is currently untested. The documentation link at the end of the message ("See MNE installation documentation for details.") would be more useful if it included an actual URL.

Thanks for the detailed feedback. I’ll work on these changes and update the PR soon.

@wmvanvliet
Copy link
Copy Markdown
Contributor

I think @ayuclan's approach is good. For one, all the input parameters are already explicitly checked by the code. Second, if something fails in the mri_watershed command, such as an input file path being wrong, we raise a CalledProcessError, not a FileNotFoundError. To be extra safe, we could use the raise ... from construction to also have the original FileNotFoundError in the error message. In the unlikely event the error was not raised because mri_watershed is not in the path, it will show up. I'll add a comment with the suggested change.

@JiwaniZakir I know you use AI and not always disclose it. Was your comment AI generated?

Comment thread mne/bem.py Outdated
Comment thread mne/bem.py Outdated
@wmvanvliet
Copy link
Copy Markdown
Contributor

I would be ok with not adding a unit test for this one, because it would be a little tricky. The unittest we have for make_watershed_bem has a @requires_freesurfer("mri_watershed") decorator which makes sure the test only runs if freesurfer has been installed correctly. So we can't test for installation issues inside that test :) I'm not a fan of mocking run_subprocess_env to return a FileNotFoundError, because what we would want to test is that we get the proper error message when we have an actual installation issue.

ayuclan added a commit to ayuclan/mne-python that referenced this pull request Apr 12, 2026
Added changelog entry for PR mne-tools#13790 describing the improved error message when FreeSurfer executable is not found.
@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 12, 2026

Thank you for the review and approval! I’ve addressed the suggestions and added the changelog entry. Please let me know if anything else is needed.

@wmvanvliet
Copy link
Copy Markdown
Contributor

The style checker is complaining:

 
E501 Line too long (98 > 88)
    --> mne/bem.py:1325:89
     |
1323 |             "- FREESURFER_HOME is set\n"
1324 |             "- $FREESURFER_HOME/bin is in your PATH\n"
1325 |             "- You started Python/Jupyter from a terminal where SetupFreeSurfer.sh is sourced\n\n"
     |                                                                                         ^^^^^^^^^^
1326 |             "See MNE installation documentation for details."
1327 |         ) from e
     |

looks like line 1325 is too long now and needs to be broken up.

Also, if you create an account on circleci, then the documentation building bot can run for you and see if your changelog entry renders properly.

@wmvanvliet
Copy link
Copy Markdown
Contributor

Also, to give you proper credit, can you add your name to doc/names.inc, and end your changelog entry with , by `Ayushi Satodiya`_ ? (see any of the other changelog entries on how we always end them with our names).

ayuclan added a commit to ayuclan/mne-python that referenced this pull request Apr 13, 2026
@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 13, 2026 via email

@wmvanvliet
Copy link
Copy Markdown
Contributor

Let's see if we can make all the checkmarks green :) Currently, circleci refuses to run because you have not registered an account with them yet. Could you click on one of the failed ci/circleci tests and then signup for circleci?

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 13, 2026 via email

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 13, 2026

Hello,

I’ve set up CircleCI and re-triggered the checks—those are now passing.

There’s one remaining failure on Python 3.14 (test_3d_backend[pyvistaqt]), likely due to a VTK API change (GetCapacity vs Capacity). I couldn’t find any direct usage in the repo, so it seems dependency-related.

Should I handle this, or ignore for now?

@drammock
Copy link
Copy Markdown
Member

There’s one remaining failure on Python 3.14 (test_3d_backend[pyvistaqt]), likely due to a VTK API change (GetCapacity vs Capacity). I couldn’t find any direct usage in the repo, so it seems dependency-related.

Should I handle this, or ignore for now?

preferable that this gets fixed in a separate PR, since it's not related to the changes here. If you know how to fix it, feel free to open a new PR for it --- if not, someone else will do so soon.

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 14, 2026 via email

ayuclan and others added 4 commits April 15, 2026 17:23
Closes mne-tools#12917

Improved error message when FreeSurfer executable (e.g., mri_watershed) cannot be found.

- Clarifies need for proper FreeSurfer setup
- Mentions adding $FREESURFER_HOME/bin to PATH
- Notes that Python/Jupyter should be started from configured shell

This helps users diagnose common setup issues more easily.
ENH: refine FreeSurfer setup error message

Co-authored-by: Marijn van Vliet <w.m.vanvliet@gmail.com>
ENH: preserve original exception using "from e"

Co-authored-by: Marijn van Vliet <w.m.vanvliet@gmail.com>
@JiwaniZakir
Copy link
Copy Markdown

The improved error message is clear and actionable — pointing users toward $FREESURFER_HOME/bin in PATH and the shell-launch requirement covers the two most common setup pitfalls. One minor consideration: if FREESURFER_HOME isn't set at all, the message referencing it might still confuse users who haven't sourced the FreeSurfer setup script yet — worth verifying the message handles that case gracefully. Otherwise the change looks good to merge.

@ayuclan ayuclan requested a review from wmvanvliet April 17, 2026 10:09
@JiwaniZakir
Copy link
Copy Markdown

Good to know SetupFreeSurfer.sh is still the correct name — I've kept it as-is then. I've applied your suggestions for catching FileNotFoundError as e and chaining the exception with from e, which gives a cleaner traceback for users debugging setup issues.

@wmvanvliet
Copy link
Copy Markdown
Contributor

@ayuclan could you add yourself to doc/changes/names.inc?

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 17, 2026 via email

@JiwaniZakir
Copy link
Copy Markdown

The test failures due to the warning itself rather than computation differences are a real concern — if tests are asserting on stderr/stdout or using warning filters, adding a new warning will break them regardless of correctness. It might be worth auditing which specific tests failed to determine if they need updating or if the warning text/category should be adjusted to avoid triggering existing pytest.warns or -W error filters in the test suite.

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 17, 2026 via email

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 17, 2026

The test failures due to the warning itself rather than computation differences are a real concern — if tests are asserting on stderr/stdout or using warning filters, adding a new warning will break them regardless of correctness. It might be worth auditing which specific tests failed to determine if they need updating or if the warning text/category should be adjusted to avoid triggering existing pytest.warns or -W error filters in the test suite.

From the CI logs, the current failures appear related to the pyvistaqt / VTK issue on Python 3.14 rather than changes introduced in this PR.

This PR only modifies the error handling when the FreeSurfer executable is not found and does not introduce new warnings in normal execution paths.

Please let me know if you’d like me to investigate any specific failing tests further.

@JiwaniZakir
Copy link
Copy Markdown

The improvement looks useful — one thing worth considering is whether the error message should also check if $FREESURFER_HOME is set at all, since that's often the root cause when the executable isn't found, and distinguishing "env var not set" from "bin not in PATH" would make diagnosis even faster. Also, don't forget to add yourself to doc/changes/names.inc as @wmvanvliet mentioned.

ayuclan and others added 10 commits April 18, 2026 17:40
Closes mne-tools#12917

Improved error message when FreeSurfer executable (e.g., mri_watershed) cannot be found.

- Clarifies need for proper FreeSurfer setup
- Mentions adding $FREESURFER_HOME/bin to PATH
- Notes that Python/Jupyter should be started from configured shell

This helps users diagnose common setup issues more easily.
ENH: refine FreeSurfer setup error message

Co-authored-by: Marijn van Vliet <w.m.vanvliet@gmail.com>
ENH: preserve original exception using "from e"

Co-authored-by: Marijn van Vliet <w.m.vanvliet@gmail.com>
Added changelog entry for PR mne-tools#13790 describing the improved error message when FreeSurfer executable is not found.
@wmvanvliet wmvanvliet force-pushed the fix-freesurfer-error-message branch from ac3ffa2 to 97a34ef Compare April 18, 2026 14:40
@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 20, 2026

I was looking into the CircleCI failure and got curious about what’s causing it. It seems to fail during the “Merge with upstream and triage run” step with “Diverging branches can't be fast-forwarded” (exit code 128), rather than during the docs build itself.

Is this happening because the branch is out of sync with main after the force-push? Would rebasing resolve it, or is there something specific in the CI workflow behind this?

@wmvanvliet
Copy link
Copy Markdown
Contributor

I don't know why we get this error. I was thinking along the same lines as you and rebased the PR, but that didn't fix it.

@wmvanvliet
Copy link
Copy Markdown
Contributor

@larsoner could we get a little help?

@ayuclan
Copy link
Copy Markdown
Author

ayuclan commented Apr 20, 2026

I don't know why we get this error. I was thinking along the same lines as you and rebased the PR, but that didn't fix it.

Oh okay, that’s interesting. I was pretty sure it was a simple divergence issue, but if rebasing didn’t fix it then something else is going on in that merge step.

I’ll keep digging from my side as well , curious what exactly is breaking here.

Copy link
Copy Markdown
Member

@larsoner larsoner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the job is running in your fork rather than our repo. I'm not sure why that would be happening...

I'll try merging main into this branch to see if it helps (after committing my suggested change)

Comment thread doc/changes/dev/13790.bugfix.rst Outdated
@wmvanvliet
Copy link
Copy Markdown
Contributor

@ayuclan Could you open a new PR with the changes as they are now? We have no idea what is happening with this one :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide more helpful error message if FreeSurfer executables cannot be found; consider amending install docs

5 participants