Skip to content

Fix R startup on Windows when R_HOME or the user home has non-ASCII characters - #1453

Merged
DavisVaughan merged 5 commits into
mainfrom
fix/windows-non-ascii-r-home
Oct 28, 2026
Merged

DavisVaughan merged 5 commits into
mainfrom
fix/windows-non-ascii-r-home

Conversation

@juliasilge

Copy link
Copy Markdown
Member

Addresses posit-dev/positron#12303.

On Windows, ark now starts when the path to R contains non-ASCII characters. Before this change, ark exited with code 10 right after it loaded R.dll, and the kernel log showed no error. The user in the issue had ø in their user name, so both R_HOME and R_USER contained it.

The cause was in setup_r(). ark got R_HOME from get_R_HOME() and the user home from getRUser() as bytes in the native encoding. Then ark converted these bytes to UTF-8 and gave the result back to R in Rstart. The conversion used R's localeCP, but R gives localeCP a value only when it initializes its locale, later in startup. Before that, localeCP has its compiled-in default of 1252. Our application manifest makes the process code page UTF-8, so the bytes were already UTF-8. As a result, ark decoded ø (C3 B8) as CP1252 and gave R the path ...StrømHals..., which does not exist.

R_SetParams() writes this path to the R_HOME and R_USER environment variables. Then readconsolecfg() tries to find $R_USER/Rconsole and $R_HOME/etc/Rconsole. It finds neither file so it calls exit(10) (see src/gnuwin32/rui.c in R) and the Rust side didn't panic or log an error.

Changes

  • get_r_home() and get_user_home() now return a CString copy of the bytes from R, with no conversion. R gets back the same bytes that it gave. A comment here explains why we don't want to do a conversion.
  • Remove system_to_utf8(), because no code uses it now. console_to_utf8() still uses localeCP, but it runs only after R initializes its locale.

Testing

  • This change has no automated test because a test would need an R installation at a non-ASCII path on a Windows CI runner.
  • The diagnosis mostly comes from the logs in the issue and from the R 4.5.1 source, as I do not have a "real" non-ASCII home directory in Parallels or anything like that.
  • To do a manual test on Windows, you can do what I did to try to fake the problem:
    1. Install R at a path with a non-ASCII character, for example C:\Users\Strøm\R\R-4.5.1.
    2. Start an R session in Positron with this R installation. Before this change, the session exits with code 10. After this change, the session starts.
    3. Set the ark log level to trace. The R_HOME: line in the kernel log shows the correct path.

Positron Release Notes

New Features

  • N/A

Bug Fixes

@juliasilge
juliasilge marked this pull request as ready for review October 28, 2026 00:42
@juliasilge
juliasilge requested a review from jmcphers October 28, 2026 00:42
@DavisVaughan
DavisVaughan self-requested a review October 28, 2026 13:06
juliasilge and others added 3 commits October 28, 2026 09:25
Merges into #1453 

That PR isn't quite right because we can't trust `getRUser()` to return
UTF-8.

It's a complicated story with these two functions, `get_R_HOME()` and
`getRUser()`, but the gist is:

- `get_R_HOME()` is safe and returns UTF-8 in all paths it can take
because we set UTF-8 in the manifest

- `getRUser()` is _nearly_ safe, but the path that returns the
`Documents` directory was sadly broken in R up until [this past
month](wch/r-source@e1e4c5d)
and wasn't guaranteed to return UTF-8. This is a very common case for
this function.

For this reason RStudio uses `get_R_HOME()` but has a custom replacement
for `getRUser()` that fixes the UTF-8 issue. We now replicate the same
idea.

Lots more documentation inline in the comments in the code itself
Much harder to test a non-ascii `Directory` folder on CI
@DavisVaughan

Copy link
Copy Markdown
Contributor

Highly related PR is rstudio/rstudio#11726

In particular with getRUser() calling wctombs() (until R 4.7) we hit exactly this

utf8ToSystem() uses wctombs(), which relies on the current locale. Before R has been initialized, this locale has not yet been set to a UTF-8 locale, so setting to the native encoding implies setting (for example) some native code page, e.g. CP850 (ISO-8859-1; or latin1 in R)

@DavisVaughan

Copy link
Copy Markdown
Contributor

After a bit of work I can confirm this is working on a windows machine. It's hard to add integration tests for changing the Documents folder on Windows, but that was the whole point of the custom getRUser(), so I wanted to manually check all this out.

Pre patch, R_HOME set to C:\中\R-4.4.2

Endless hang or crash! As the original user reported. Makes sense, R can't find the mangled R_HOME and dies.

Pre patch, Documents set to C:\中\Documents

Here R can start up, but I get the following wrong results for R_USER. It's supposed to resolve to C:\中\Documents but getRUser() actually chokes on the UTF-8 (see Bonus below), and falls through to HOMEDRIVE + HOMEPATH which gives us the following for R_USER:

Screenshot 2026-10-28 at 3 17 12 PM

Post patch, with BOTH R_HOME set to C:\中\R-4.4.2 and Documents set to C:\中\Documents

Everything is looking good here!

Screenshot 2026-10-28 at 3 07 32 PM

I am expecting to see e4 b8 ad as the UTF-8 bytes for 中, so things look right to me.

Bonus - pre Davis's custom getRUser(), Documents set to C:\中\Documents

I wanted to prove that a custom getRUser() is REALLY needed so I walked back a few commits to after Julia's original fix but before my custom getRUser(). Here's the incorrect R_USER still being set:

Screenshot 2026-10-28 at 3 23 06 PM

Which is what getRUser() is giving us even though I had definitely set up my Documents to point at C:\中\Documents.

Screenshot 2026-10-28 at 3 32 48 PM

That is wrong! It happens because the Documents directory lookup fails due to the R bug fixed by this commit recently, and it falls through to HOMEDRIVE + HOMEPATH as mentioned above.


Here's what I did to get set up to run these manual tests:

For R_USER

Make sure R_USER and HOME aren't pre-defined env vars on your machine. Then R should fallback to your Documents directory, which it does for most windows users.

File Explorer -> Right click on Documents -> Properties -> Location

Change the location to C:\中\Documents and click Ok. Do NOT click "move all files" over.

Restart Positron and it should point there now.

For R_HOME

Copy all of C:\Program Files\R\R-4.4.2 over to C:\中\R-4.4.2.

Then you have to teach Positron about that R binary, since it won't natively find it. That was positron.r.customBinaries on my old machine.

Restart Positron.

@DavisVaughan
DavisVaughan merged commit 445aebc into main Oct 28, 2026
19 checks passed
@DavisVaughan
DavisVaughan deleted the fix/windows-non-ascii-r-home branch October 28, 2026 19:44
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants