Skip to content

Fix path resolution error for osu!stable on SMB network drives#658

Draft
skchqhdpdy wants to merge 4 commits into
tosuapp:masterfrom
skchqhdpdy:master
Draft

Fix path resolution error for osu!stable on SMB network drives#658
skchqhdpdy wants to merge 4 commits into
tosuapp:masterfrom
skchqhdpdy:master

Conversation

@skchqhdpdy

@skchqhdpdy skchqhdpdy commented Jul 9, 2026

Copy link
Copy Markdown

Description

This PR fixes an issue where tosu fails to resolve file paths correctly when osu!stable is executed from a mapped SMB network drive.

Currently, when running the client from an SMB drive, the path is incorrectly parsed and concatenated, resulting in an ENOENT error in the logs like this:

4.24.0 ┃ 00:38:28.845 Request to /Songs/.../BG.jpg% failed: ENOENT: no such file or directory, stat 'O:\124.58.110.110\aodd\osu!\Songs\731899 Gohma - Forward\BG.jpg'

My Execution Environment:

  • Windows File Explorer mapped path: O:\osu!\osu!.exe
  • Actual SMB network path: \\124.58.110.110\aodd\osu!\osu!.exe

The issue occurs because the drive letter (O:\) and the actual network IP path are improperly combined. This PR updates the path resolution logic so that osu!stable can correctly locate the files on an SMB network drive. I also made sure that the path resolution for osu!lazer remains unaffected and continues to work without any issues.

Demonstration

Here is a video demonstrating the issue before the fix, and the working state after applying the patch:
🎥 Watch the Before & After Test on YouTube

Note

As I am a beginner in TypeScript, the code modifications in this PR were guided and written with the assistance of Anthropic's Claude AI. I have built the .exe locally with these changes and tested it in my environment to confirm that everything works perfectly.

Oh, I forgot to mention that. The Lazer client has absolutely nothing to do with this issue.

@GabuTheDev GabuTheDev added ai-written Not human made :( area:server The nodejs backend of tosu. labels Jul 9, 2026
@KotRikD

KotRikD commented Jul 9, 2026

Copy link
Copy Markdown
Member

@codex review (take additional review on regex)

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: c170329aff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@storycraft storycraft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The fix must be applied on only windows. It's invalid to return a path starting with double slash on non-windows os. Also mind adding a comment to this special handling.

@skchqhdpdy

Copy link
Copy Markdown
Author

My reply was a little late because I was installing Ubuntu Desktop on VMware.
As you suggested, I’ve modified it to run only in a Windows environment. Claude AI wrote the code for this as well.

At first glance, it doesn’t seem to make much difference in an Ubuntu environment, but as you pointed out, it’s correct not to use a double slash in non-Windows environments, so I’ve revised it again.

The first image is a screenshot from the c170329 commit.
The second image is a screenshot from the bef4144 commit.
1_c170329
2_bef4144

Comment thread packages/tosu/src/utils/converters.ts Outdated
return normalize(join(...cleaned));
const result = normalize(join(...cleaned));

return isUnc && !result.startsWith(sep + sep) ? sep + result : result;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If it's already isUnc. Is it really need to additional comparsion of sep+sep (I guess that's const a separator from path library)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

After hearing your suggestion and checking it myself, I confirmed that the value of the result variable is outputted as \124.58.110.110\aodd\osu!.

Therefore, I determined that the conditional statement !result.startsWith(sep + sep) you mentioned is unnecessary, so I modified the code to return isUnc ? sep + result : result;.

Please let me know if you have any other suggestions or changes.

@storycraft

Copy link
Copy Markdown
Member

Fix lint

@skchqhdpdy

Copy link
Copy Markdown
Author

Since I'm not very familiar with TypeScript, I asked Gemini, and it told me to run two commands. So I ran them and then committed the changes. I'll post the results below.

PS C:\Users\skchqhdpdy\Downloads\tosu> pnpm run lint:fix
 WARN  Unsupported engine: wanted: {"node":">=24.14.0 <25.0.0"} (current: {"node":"v22.15.0","pnpm":"10.10.0"})

> @4.24.0 lint:fix C:\Users\skchqhdpdy\Downloads\tosu
> eslint --fix --ext .ts,.d.ts .

PS C:\Users\skchqhdpdy\Downloads\tosu> pnpm run prettier:fix                                                                                                                  
 WARN  Unsupported engine: wanted: {"node":">=24.14.0 <25.0.0"} (current: {"node":"v22.15.0","pnpm":"10.10.0"})

> @4.24.0 prettier:fix C:\Users\skchqhdpdy\Downloads\tosu
> prettier --write "**/*.{js,jsx,ts,tsx,css}"

packages/common/enums/country.ts 101ms (unchanged)
packages/common/enums/logging.ts 21ms (unchanged)
packages/common/enums/osu.ts 71ms (unchanged)
packages/common/enums/tosu.ts 10ms (unchanged)
packages/common/index.ts 12ms (unchanged)
packages/common/utils/arguments.ts 44ms (unchanged)
packages/common/utils/config.ts 166ms (unchanged)
packages/common/utils/config.types.ts 22ms (unchanged)
packages/common/utils/context.ts 5ms (unchanged)
packages/common/utils/directories.ts 36ms (unchanged)
packages/common/utils/downloader.ts 42ms (unchanged)
packages/common/utils/ingame.ts 8ms (unchanged)
packages/common/utils/json.ts 6ms (unchanged)
packages/common/utils/logger.ts 46ms (unchanged)
packages/common/utils/manipulation.ts 21ms (unchanged)
packages/common/utils/platforms.ts 6ms (unchanged)
packages/common/utils/progress.ts 23ms (unchanged)
packages/common/utils/sleep.ts 6ms (unchanged)
packages/common/utils/unzip.ts 6ms (unchanged)
packages/ingame-overlay-updater/src/index.ts 21ms (unchanged)
packages/ingame-overlay/preload/index.ts 5ms (unchanged)
packages/ingame-overlay/renderer/ingame.css 86ms (unchanged)
packages/ingame-overlay/renderer/ingame.js 165ms (unchanged)
packages/ingame-overlay/src/dev.ts 6ms (unchanged)
packages/ingame-overlay/src/index.ts 22ms (unchanged)
packages/ingame-overlay/src/keybind.ts 10ms (unchanged)
packages/ingame-overlay/src/manager.ts 25ms (unchanged)
packages/ingame-overlay/src/page.ts 6ms (unchanged)
packages/ingame-overlay/src/process.ts 31ms (unchanged)
packages/ingame-overlay/src/protocol.ts 11ms (unchanged)
packages/ingame-overlay/types/files.d.ts 4ms (unchanged)
packages/server/index.ts 16ms (unchanged)
packages/server/router/assets.ts 9ms (unchanged)
packages/server/router/index.ts 82ms (unchanged)
packages/server/router/scApi.ts 8ms (unchanged)
packages/server/router/socket.ts 20ms (unchanged)
packages/server/router/v1.ts 15ms (unchanged)
packages/server/router/v2.ts 20ms (unchanged)
packages/server/scripts/beatmapFile.ts 20ms (unchanged)
packages/server/utils/commands.ts 23ms (unchanged)
packages/server/utils/counters.ts 138ms (unchanged)
packages/server/utils/counters.types.ts 54ms (unchanged)
packages/server/utils/directories.ts 39ms (unchanged)
packages/server/utils/hashing.ts 8ms (unchanged)
packages/server/utils/homepage.ts 8ms (unchanged)
packages/server/utils/htmls.ts 16ms (unchanged)
packages/server/utils/http.ts 45ms (unchanged)
packages/server/utils/index.ts 19ms (unchanged)
packages/server/utils/parseSettings.ts 28ms (unchanged)
packages/server/utils/report.ts 40ms (unchanged)
packages/server/utils/socket.ts 41ms (unchanged)
packages/tosu/src/api/types/sc.ts 12ms (unchanged)
packages/tosu/src/api/types/v1.ts 30ms (unchanged)
packages/tosu/src/api/types/v2.ts 37ms (unchanged)
packages/tosu/src/api/utils/buildResult.ts 56ms (unchanged)
packages/tosu/src/api/utils/buildResultSC.ts 40ms (unchanged)
packages/tosu/src/api/utils/buildResultV2.ts 104ms (unchanged)
packages/tosu/src/api/utils/buildResultV2Precise.ts 13ms (unchanged)
packages/tosu/src/index.ts 11ms (unchanged)
packages/tosu/src/instances/index.ts 40ms (unchanged)
packages/tosu/src/instances/lazerInstance.ts 42ms (unchanged)
packages/tosu/src/instances/manager.ts 32ms (unchanged)
packages/tosu/src/instances/osuInstance.ts 29ms (unchanged)
packages/tosu/src/memory/index.ts 20ms (unchanged)
packages/tosu/src/memory/lazer.ts 364ms (unchanged)
packages/tosu/src/memory/stable.ts 152ms (unchanged)
packages/tosu/src/memory/types.ts 16ms (unchanged)
packages/tosu/src/states/bassDensity.ts 13ms (unchanged)
packages/tosu/src/states/beatmap.ts 93ms (unchanged)
packages/tosu/src/states/gameplay.ts 142ms (unchanged)
packages/tosu/src/states/global.ts 17ms (unchanged)
packages/tosu/src/states/index.ts 2ms (unchanged)
packages/tosu/src/states/lazerMultiSpectating.ts 7ms (unchanged)
packages/tosu/src/states/menu.ts 15ms (unchanged)
packages/tosu/src/states/rankedplay.ts 7ms (unchanged)
packages/tosu/src/states/resultScreen.ts 28ms (unchanged)
packages/tosu/src/states/settings.ts 13ms (unchanged)
packages/tosu/src/states/tourney.ts 14ms (unchanged)
packages/tosu/src/states/types.ts 4ms (unchanged)
packages/tosu/src/states/user.ts 9ms (unchanged)
packages/tosu/src/utils/bindings.ts 12ms (unchanged)
packages/tosu/src/utils/calculators.ts 25ms (unchanged)
packages/tosu/src/utils/converters.ts 17ms (unchanged)
packages/tosu/src/utils/hitResult.ts 22ms (unchanged)
packages/tosu/src/utils/multiplayer.types.ts 9ms (unchanged)
packages/tosu/src/utils/osuMods.ts 51ms (unchanged)
packages/tosu/src/utils/osuMods.types.ts 34ms (unchanged)
packages/tosu/src/utils/settings.types.ts 9ms (unchanged)
packages/tsprocess/src/index.ts 6ms (unchanged)
packages/tsprocess/src/process.ts 35ms (unchanged)
packages/updater/index.ts 24ms (unchanged)
PS C:\Users\skchqhdpdy\Downloads\tosu> 
PS C:\Users\skchqhdpdy\Downloads\tosu> pnpm run lint:ci                                                                                                                                           
 WARN  Unsupported engine: wanted: {"node":">=24.14.0 <25.0.0"} (current: {"node":"v22.15.0","pnpm":"10.10.0"})

> @4.24.0 lint:ci C:\Users\skchqhdpdy\Downloads\tosu
> eslint --ext .ts,.d.ts .

PS C:\Users\skchqhdpdy\Downloads\tosu> pnpm run prettier:ci 
 WARN  Unsupported engine: wanted: {"node":">=24.14.0 <25.0.0"} (current: {"node":"v22.15.0","pnpm":"10.10.0"})

> @4.24.0 prettier:ci C:\Users\skchqhdpdy\Downloads\tosu
> prettier --check "**/*.{js,jsx,ts,tsx,css}"

Checking formatting...
All matched files use Prettier code style!
PS C:\Users\skchqhdpdy\Downloads\tosu>

@cyperdark
cyperdark requested review from GabuTheDev and KotRikD and removed request for cyperdark July 15, 2026 03:20
@cyperdark
cyperdark marked this pull request as draft July 15, 2026 05:27
@cyperdark

Copy link
Copy Markdown
Collaborator

on pause due to internal discussions

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

Labels

ai-written Not human made :( area:server The nodejs backend of tosu.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants