Skip to content

fix: possible fix for non-proton games launching#90

Merged
Nat3z merged 4 commits intomainfrom
fix/wine-dll
Feb 26, 2026
Merged

fix: possible fix for non-proton games launching#90
Nat3z merged 4 commits intomainfrom
fix/wine-dll

Conversation

@Nat3z
Copy link
Owner

@Nat3z Nat3z commented Feb 26, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Improved parsing and error handling for game launcher execution, resulting in more reliable initialization of games launched through compatibility layers.
    • Ensured launcher arguments and executable selection are preserved correctly during startup, improving reliability for edge-case wrapper commands and reducing launch failures.

@vercel
Copy link

vercel bot commented Feb 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
open-game-installer-web Ready Ready Preview, Comment Feb 26, 2026 4:44am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Warning

Rate limit exceeded

@Nat3z has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 12 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between a88f107 and 8386250.

📒 Files selected for processing (1)
  • application/src/electron/handlers/handler.library.ts
📝 Walkthrough

Walkthrough

Refines parsing and execution of UMU/Steam wrapper commands: detects collapsed launcher patterns, adds a steamArgSeparator, reparses launcher prefixes when needed, guards against empty parse results, replaces wrapped executables with the canonical launch executable, and uses shell-based spawn for wrapper paths.

Changes

Cohort / File(s) Summary
Wrapper Command Parsing & Execution
application/src/electron/handlers/handler.library.ts
Adds steamArgSeparator and detection for collapsed launcher tokens; reconstructs and reparses launcher prefix when detected; returns parse-error on empty parsed tokens; always replaces trailing executable with appInfo.launchExecutable; enables shell: true for wrapper spawns; preserves UMU env handling and logging while expanding control flow for new parsing cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through tokens, split and rejoined,
Found the hidden launcher where arguments were coined,
Replaced the brave exe with the one you should run,
Launched with a shell and the parsing is done—
Tiny paws, tidy code, a job well spun.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix in the changeset - handling non-proton games launching by improving wrapper command parsing and spawn logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/wine-dll

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Typecheck Passed - All type checks successful!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@application/src/electron/handlers/handler.library.ts`:
- Line 261: The spawn call in handler.library.ts is using shell: true which
causes pre-tokenized args to be joined and re-parsed by a shell; change the
spawn options to use shell: false (or remove the shell option to use default) so
the args array passed to spawn is used as a true argv vector; locate the spawn
invocation in this file (the function/method that calls spawn where shell: true
is set) and update the options object to shell: false, and if any arguments
currently rely on shell expansion or quoting, rework them to be safely passed as
separate entries in the args array or explicitly escape them before passing.
- Around line 233-237: The parsed result from shell-quote (parsed) may contain
non-string tokens (operator/comment/glob objects) which, when appended to
fixedArgs or coerced with .toString() later, become "[object Object]" and break
execution; update the logic around wrapperCommand parsing (parsed) and fixedArgs
construction to validate token types: explicitly ensure every token in parsed is
a string (or nicely stringify only safe token types), reject/return an error if
any non-string tokens are present, or filter/transform allowed tokens to strings
before building fixedArgs that includes appInfo.launchExecutable, and change the
code paths that rely on .toString() (lines that reference fixedArgs usage) to
assume only validated string tokens.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between a6c43e8 and 3a0fcd4.

📒 Files selected for processing (1)
  • application/src/electron/handlers/handler.library.ts

Comment on lines +233 to 237
if (parsed.length === 0) {
return { success: false, error: 'Wrapper command could not be parsed' };
}
const fixedArgs = [...parsed, appInfo.launchExecutable];

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

❓ Verification inconclusive

Script executed:

# First, let's look at the file and the specific lines mentioned
cat -n application/src/electron/handlers/handler.library.ts | sed -n '230,265p'

Repository: Nat3z/OpenGameInstaller


Repository: Nat3z/OpenGameInstaller
Exit code: 0

stdout:

   230	    }
   231	  }
   232	
   233	  if (parsed.length === 0) {
   234	    return { success: false, error: 'Wrapper command could not be parsed' };
   235	  }
   236	  const fixedArgs = [...parsed, appInfo.launchExecutable];
   237	
   238	  return await new Promise((resolve) => {
   239	    const effectiveLaunchEnv = getEffectiveLaunchEnv(appInfo);
   240	    const effectiveDllOverrides = getEffectiveDllOverrides(appInfo);
   241	    const dllOverrideString = buildDllOverrides(effectiveDllOverrides);
   242	    const baseEnv = {
   243	      ...process.env,
   244	      ...(launchEnv ?? {}),
   245	      ...effectiveLaunchEnv,
   246	      PROTON_LOG: '1',
   247	    };
   248	    const env = appInfo.umu
   249	      ? {
   250	          ...baseEnv,
   251	          STEAM_COMPAT_DATA_PATH: getUmuWinePrefix(appInfo.umu.umuId),
   252	          WINEPREFIX: getUmuWinePrefix(appInfo.umu.umuId),
   253	          ...(dllOverrideString ? { WINEDLLOVERRIDES: dllOverrideString } : {}),
   254	        }
   255	      : baseEnv;
   256	
   257	    const wrappedChild = spawn(
   258	      parsed[0].toString(),
   259	      fixedArgs.slice(1).map((x) => x.toString()),
   260	      {
   261	        shell: true,
   262	        cwd: appInfo.cwd,
   263	        env,
   264	        stdio: ['ignore', 'pipe', 'pipe'],
   265	      }

Script executed:

# Also check if shell-quote is in package.json or installed
find . -name "package.json" -type f -exec grep -l "shell-quote" {} \;

Repository: Nat3z/OpenGameInstaller


Repository: Nat3z/OpenGameInstaller
Exit code: 0

stdout:

./application/package.json

shell-quote parse() return type token types operator objects


In shell-quote, parse() returns an array of “tokens”:

  • TypeScript return type: ParseEntry[] (or Array<ParseEntry | T> with the generic overload). [1]
  • Token variants (ParseEntry): [1]
    • string (a normal word/argument)
    • { op: ControlOperator } (a shell/control operator token)
    • { op: "glob"; pattern: string } (a glob token)
    • { comment: string } (a # ... comment token)

Operator token values (ControlOperator) include:
"||" | "&&" | ";;" | "|&" | "<(" | ">>" | ">&" | "&" | ";" | "(" | ")" | "|" | "<" | ">". [1]

Example outputs (operators/comments become objects):
parse('beep || boop > /byte')['beep', { op: '||' }, 'boop', { op: '>' }, '/byte']
parse('beep > boop # > kaboom')['beep', { op: '>' }, 'boop', { comment: '> kaboom' }] [2]

Env function overload detail: if env(key) returns an object, it’s inserted into the returned token array “like the operator objects”. [1]

Sources: [1] @types/shell-quote index.d.ts (UNPKG) (app.unpkg.com), [2] shell-quote README on npm (examples/behavior) (npmjs.com)

Citations:


Script executed:

cat -n application/src/electron/handlers/handler.library.ts | sed -n '210,235p'

Repository: Nat3z/OpenGameInstaller


Repository: Nat3z/OpenGameInstaller
Exit code: 0

stdout:

   210	  const verbWithSpaces = ` ${verb} `;
   211	  const steamArgSeparator = ' -- ';
   212	  const verbIndexInString = wrapperCommand.indexOf(verbWithSpaces);
   213	  let parsed: ReturnType<typeof shellQuoteParse>;
   214	  if (verbIndexInString !== -1) {
   215	    const prefix = wrapperCommand.slice(0, verbIndexInString).trimEnd();
   216	    parsed = shellQuoteParse(prefix);
   217	    parsed.push(verb);
   218	    // Everything after " waitforexitandrun " is the exe path (may contain spaces);
   219	    // we replace it with the canonical path, so we don't parse the suffix.
   220	  } else {
   221	    // Non-Proton command variants usually end with " -- <exe>".
   222	    // Parse only the prefix up to the last separator, then replace <exe>.
   223	    const lastSeparatorInString = wrapperCommand.lastIndexOf(steamArgSeparator);
   224	    if (lastSeparatorInString !== -1) {
   225	      const prefix = wrapperCommand.slice(0, lastSeparatorInString).trimEnd();
   226	      parsed = shellQuoteParse(prefix);
   227	      parsed.push('--');
   228	    } else {
   229	      parsed = shellQuoteParse(wrapperCommand);
   230	    }
   231	  }
   232	
   233	  if (parsed.length === 0) {
   234	    return { success: false, error: 'Wrapper command could not be parsed' };
   235	  }

Script executed:

# Search for where this function is called and what input is passed
rg -B 5 -A 5 "parse\(" application/src/electron/handlers/handler.library.ts | head -40

Repository: Nat3z/OpenGameInstaller


Repository: Nat3z/OpenGameInstaller
Exit code: 0


Validate parsed token types before argv construction.

The wrapperCommand is user-supplied (lines 215, 225, 229) and parsed via shell-quote. The parse function returns mixed token types: strings, operator objects ({ op: '||' | '&&' | ... }), globs, and comments. Line 233 only checks emptiness; it does not validate token types. When non-string tokens reach lines 258–259, their .toString() coercion produces "[object Object]" strings, breaking the wrapper execution.

Suggested fix
-  if (parsed.length === 0) {
+  if (parsed.length === 0 || parsed.some((t) => typeof t !== 'string')) {
     return { success: false, error: 'Wrapper command could not be parsed' };
   }
-  const fixedArgs = [...parsed, appInfo.launchExecutable];
+  const parsedStrings = parsed as string[];
+  const fixedArgs = [...parsedStrings, appInfo.launchExecutable];
...
-      parsed[0].toString(),
-      fixedArgs.slice(1).map((x) => x.toString()),
+      fixedArgs[0],
+      fixedArgs.slice(1),

Also applies to: 258–259

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@application/src/electron/handlers/handler.library.ts` around lines 233 - 237,
The parsed result from shell-quote (parsed) may contain non-string tokens
(operator/comment/glob objects) which, when appended to fixedArgs or coerced
with .toString() later, become "[object Object]" and break execution; update the
logic around wrapperCommand parsing (parsed) and fixedArgs construction to
validate token types: explicitly ensure every token in parsed is a string (or
nicely stringify only safe token types), reject/return an error if any
non-string tokens are present, or filter/transform allowed tokens to strings
before building fixedArgs that includes appInfo.launchExecutable, and change the
code paths that rely on .toString() (lines that reference fixedArgs usage) to
assume only validated string tokens.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Typecheck Passed - All type checks successful!

@Nat3z
Copy link
Owner Author

Nat3z commented Feb 26, 2026

[wrapper stderr] <3>pv-adverb[277355]: E: Failed to execute child process ?/home/deck/.local/share/Steam/steamapps/common/Proton? (No such file or directory)

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Typecheck Passed - All type checks successful!

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Typecheck Passed - All type checks successful!

@Nat3z Nat3z merged commit 45b0c0c into main Feb 26, 2026
6 checks passed
@Nat3z Nat3z deleted the fix/wine-dll branch February 26, 2026 04:47
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.

1 participant