Skip to content

Conversation

@abe238
Copy link
Contributor

@abe238 abe238 commented Dec 31, 2025

Summary

  • Updated parsePythonCommand to check for path separators BEFORE existsSync to properly handle paths that may not exist yet
  • Added macOS Application Support and Windows AppData patterns to ALLOWED_PATH_PATTERNS for Electron userData venv paths
  • Changed python-env-manager to use execFileSync instead of execSync to avoid shell interpretation issues with spaces

Problem

When using the packaged app on macOS, the venv Python path contains spaces:
/Users/user/Library/Application Support/App/python-venv/bin/python

This was causing spawn ENOENT errors during merge operations because the path was being incorrectly split at the space character.

Root Cause

The parsePythonCommand function was checking existsSync() before checking if the path looked like a file path. If the file didn't exist (e.g., during initial setup), and the path wasn't recognized as a path, it would fall through to splitting on spaces.

Fix

  1. Reorder checks: Check for path separators (/ or \) FIRST, before checking file existence
  2. Add userData patterns: Added regex patterns for:
    • macOS: /Users/<user>/Library/Application Support/<app>/python-venv/bin/python
    • Windows: C:\Users\<user>\AppData\Roaming\<app>\python-venv\Scripts\python.exe
  3. Use execFileSync: Changed python-env-manager.ts to use execFileSync with shell: false to avoid shell interpretation issues

Test Plan

  • Test merge operation on macOS with packaged app
  • Test merge operation on Windows with packaged app
  • Verify venv creation still works with paths containing spaces

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved Python environment detection for installations in paths containing spaces, including macOS Application Support and Windows Roaming locations.
    • Commands that look like file paths are now accepted as whole paths even if the file isn't present yet, avoiding incorrect splitting.
    • Improved resolution of the actual Python executable to avoid shell interpretation issues while preserving timeout behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Reorders Python command parsing to treat path-like strings (contain / or \ and not starting with -) before existence checks, extends allowed path regexes for macOS/Windows locations, and swaps shell-based execSync for execFileSync using parsed cmd+args to resolve Python executables.

Changes

Cohort / File(s) Summary
Path Detection & Pattern Recognition
apps/frontend/src/main/python-detector.ts
parsePythonCommand now checks for path separators first and returns the full path-like string (no space-splitting) even if the file doesn't yet exist; expanded ALLOWED_PATH_PATTERNS to include macOS Application Support and Windows Roaming-style Python paths; docs/comments updated.
Command Execution Refactor
apps/frontend/src/main/python-env-manager.ts
findSystemPython now uses execFileSync with the parsePythonCommand output (cmd + args) instead of execSync to avoid shell interpretation and correctly handle commands containing spaces; preserves timeout and error semantics.

Sequence Diagram(s)

sequenceDiagram
  %% Styling for clarity
  participant App as Frontend
  participant Detector as python-detector
  participant Child as child_process (execFileSync)
  participant OS as System FS / PATH

  App->>Detector: parsePythonCommand(rawCommand)
  Detector-->>App: { cmd, args, isPathLike }
  alt isPathLike == true
    App->>Child: execFileSync(cmd, args, shell:false, timeout)
    Child->>OS: spawn executable directly
    OS-->>Child: executable path or error
    Child-->>App: stdout / resolved path or error
  else not path-like
    App->>Child: execFileSync(cmd, args, shell:false, timeout)
    Child->>OS: resolve via PATH / system
    OS-->>Child: resolved path or error
    Child-->>App: stdout / resolved path or error
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug, area/frontend, os/macos, priority/medium

Suggested reviewers

  • MikeeBuilds
  • AlexMadera
  • AndyMik90

Poem

🐰 I hopped through paths both near and far,
Found slashes, spaces — a guiding star.
No shell tricks now, I call direct,
Split the args and check effect.
Python found — a rabbit’s clever art. 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: handling Python paths with spaces correctly, which is the core problem this PR solves.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54bb603 and 01f6300.

📒 Files selected for processing (2)
  • apps/frontend/src/main/python-detector.ts
  • apps/frontend/src/main/python-env-manager.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/frontend/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
apps/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use useTranslation() hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
apps/frontend/**/*.{ts,tsx}

⚙️ CodeRabbit configuration file

apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
🧬 Code graph analysis (1)
apps/frontend/src/main/python-env-manager.ts (4)
apps/frontend/src/main/python-detector.ts (1)
  • parsePythonCommand (219-272)
apps/frontend/scripts/verify-python-bundling.cjs (1)
  • pythonCmd (65-65)
apps/frontend/src/main/changelog/changelog-service.ts (1)
  • pythonPath (104-109)
apps/frontend/src/main/title-generator.ts (1)
  • pythonPath (48-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (6)
apps/frontend/src/main/python-detector.ts (4)

211-214: LGTM - Clear documentation of the requirements.

The updated documentation clearly states the critical requirement: paths with spaces must never be split. This helps future maintainers understand the importance of the parsing order.


237-255: Excellent fix - path detection before existence check solves the root cause.

This reordering is the key to solving the issue described in the PR. By checking for path separators (/ or \) BEFORE checking file existence, the function now correctly handles:

  1. Existing paths with spaces - returned as-is
  2. Non-existent paths with spaces (e.g., during venv creation) - returned as-is instead of being split
  3. Inaccessible paths - returned as-is

The logic is sound: any string containing path separators that doesn't start with - is treated as a path and never split on spaces.

To confirm this fix works as expected, please verify the test plan mentioned in the PR objectives has been completed:

  • ✓ Test merge operation on macOS with packaged app (paths like /Users/user/Library/Application Support/...)
  • ✓ Test merge operation on Windows with packaged app (paths like C:\Users\user\AppData\Roaming\...)
  • ✓ Verify venv creation still works with paths containing spaces

Can you confirm these tests have passed?


257-264: LGTM - Correct placement and clear comments.

The existence check and space-splitting logic are now properly ordered after the path detection. The comments clearly explain the control flow at this point.


306-320: Regex patterns verified correctly for intended use cases.

The macOS Application Support and Windows AppData patterns both match their intended Electron userData paths and correctly handle the tested edge cases:

  • Both match paths with spaces in app names
  • Both support python-venv, .venv, and venv directory conventions
  • Both reject paths missing the proper Application Support/AppData/Roaming structure
  • Both prevent directory traversal attempts

Patterns are production-ready.

apps/frontend/src/main/python-env-manager.ts (2)

1-1: LGTM - Imports correctly updated.

Both execFileSync and parsePythonCommand are now properly imported. This resolves the previous review comment about the missing parsePythonCommand import.

Also applies to: 6-6


204-210: Excellent change - execFileSync with shell: false prevents path splitting.

This change is the complementary fix to the parsePythonCommand updates. By using execFileSync instead of execSync and setting shell: false, the code now:

  1. Prevents shell interpretation that would split paths with spaces
  2. Properly handles parsed commands like "py -3" by spreading the args array: ['-3', '-c', 'import sys; print(sys.executable)']
  3. Preserves path integrity for paths like /Users/user/Library/Application Support/App/python-venv/bin/python
  4. Maintains the same timeout (5000ms) and other behavior

The logic is correct:

  • For "python3"execFileSync("python3", ['-c', '...'])
  • For "py -3"execFileSync("py", ['-3', '-c', '...'])
  • For "/path/with spaces/python"execFileSync("/path/with spaces/python", ['-c', '...'])

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

@github-actions
Copy link

github-actions bot commented Dec 31, 2025

All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @abe238, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical issue where Python paths containing spaces, particularly those found in Electron application data directories on macOS and Windows, were causing spawn ENOENT errors. The changes ensure that such paths are correctly parsed and executed by reordering path validation logic, expanding the set of recognized path patterns, and adopting execFileSync for command execution to bypass shell interpretation problems. This significantly enhances the stability and compatibility of Python environment management within the application.

Highlights

  • Improved Python Path Parsing: The parsePythonCommand function has been updated to prioritize checking for path separators before verifying file existence. This ensures that Python paths containing spaces (e.g., in macOS Application Support directories) are correctly identified as single paths and not incorrectly split into multiple arguments, even if the file doesn't exist yet during initial setup.
  • Expanded Allowed Path Patterns: New regex patterns have been added to ALLOWED_PATH_PATTERNS to explicitly recognize common Electron userData virtual environment paths on both macOS (e.g., /Library/Application Support/) and Windows (e.g., AppData/Roaming/). These paths frequently contain spaces and are now properly validated.
  • Switched to execFileSync for Robust Execution: The python-env-manager.ts file now uses execFileSync instead of execSync when resolving the actual Python executable path. By setting shell: false, this change prevents shell interpretation issues that could arise from spaces within Python paths, ensuring more reliable command execution.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively resolves the issue of handling Python paths with spaces, which was causing errors on platforms like macOS. The core logic change in parsePythonCommand to prioritize path structure over file existence is a solid fix. Additionally, switching to execFileSync from execSync is a great improvement for both security and robustness, preventing shell interpretation issues. The new regex patterns for Electron's userData paths on both macOS and Windows are also a necessary addition. I've included a couple of suggestions to consolidate similar regular expressions for improved maintainability. Overall, this is a well-executed fix.

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: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 203a970 and 54bb603.

📒 Files selected for processing (2)
  • apps/frontend/src/main/python-detector.ts
  • apps/frontend/src/main/python-env-manager.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/frontend/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
apps/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use useTranslation() hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
apps/frontend/**/*.{ts,tsx}

⚙️ CodeRabbit configuration file

apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.

Files:

  • apps/frontend/src/main/python-env-manager.ts
  • apps/frontend/src/main/python-detector.ts
🪛 GitHub Actions: CI
apps/frontend/src/main/python-env-manager.ts

[error] 205-205: TypeScript error: Cannot find name 'parsePythonCommand'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (4)
apps/frontend/src/main/python-detector.ts (3)

211-213: Excellent documentation enhancement.

The added emphasis on handling paths with spaces is clear and directly addresses the root cause described in the PR. This will help prevent future regressions.


237-255: Core fix correctly implements path-with-spaces handling.

The reordering of checks is the key improvement:

  1. Path separator detection now happens before existence checks
  2. Paths with separators are returned as-is without splitting on spaces
  3. This correctly handles venv paths that don't exist yet during setup

The logic is sound and directly addresses the root cause of the ENOENT errors.


306-309: Pattern coverage is correct—no changes needed.

The added patterns accurately match Electron userData paths:

  • macOS: /Users/<user>/Library/Application Support/<app>/ is the standard userData location; non-standard home directories are not a practical concern.
  • Windows: AppData\Roaming\<app>\ is the correct userData location; AppData\Local is used only for system Python installations (already handled by line 318).
  • App name matching: [^/]+ and [^\\]+ correctly capture all app names while preventing directory traversal.

The generic patterns at lines 313–315 provide fallback coverage for Linux and other venv naming variations.

apps/frontend/src/main/python-env-manager.ts (1)

204-210: Correct fix for shell interpretation issues with spaces.

The change from execSync to execFileSync with shell: false is the right approach:

  • Prevents the shell from splitting paths at spaces
  • Uses parsePythonCommand to correctly parse the command
  • Maintains the same 5-second timeout for safety

This change works correctly once the missing import is added (see previous comment).

Note: This comment assumes the missing parsePythonCommand import will be added as suggested in the previous review comment.

@AlexMadera AlexMadera self-assigned this Dec 31, 2025
- Updated parsePythonCommand to check for path separators BEFORE
  existsSync to properly handle paths that may not exist yet
- Added macOS Application Support and Windows AppData patterns to
  ALLOWED_PATH_PATTERNS for Electron userData venv paths
- Changed python-env-manager to use execFileSync instead of execSync
  to avoid shell interpretation issues with spaces

Fixes spawn ENOENT errors when venv Python path contains spaces,
e.g., /Users/user/Library/Application Support/App/python-venv/bin/python

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: Abe Diaz (@abe238) <[email protected]>
@abe238 abe238 force-pushed the fix/python-path-spaces branch from 54bb603 to 890704c Compare December 31, 2025 07:14
Copy link
Collaborator

@AlexMadera AlexMadera left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

Merge Verdict: ✅ READY TO MERGE

No blocking issues found

Risk Assessment

Factor Level Notes
Complexity Low Based on lines changed
Security Impact Low Based on security findings
Scope Coherence Good Based on structural review

Findings Summary

  • Medium: 1 issue(s)
  • Low: 3 issue(s)

Generated by Auto Claude PR Review

Findings (4 selected of 4 total)

🟡 [MEDIUM] getPythonVersion still uses execSync with string interpolation

📁 apps/frontend/src/main/python-detector.ts:130

The getPythonVersion function at line 130 still uses execSync(${pythonCmd} --version) which could fail for paths containing spaces. This is inconsistent with the PR's goal of fixing space handling. While this function is primarily called with simple command names, the pattern should be updated for consistency with the execFileSync approach used elsewhere.

Suggested fix:

Update getPythonVersion to use parsePythonCommand() and execFileSync similar to verifyIsPython(): `const [cmd, args] = parsePythonCommand(pythonCmd); const version = execFileSync(cmd, [...args, '--version'], { stdio: 'pipe', timeout: 5000, windowsHide: true, shell: false }).toString().trim();`

🔵 [LOW] Edge case regression for files with spaces in name

📁 apps/frontend/src/main/python-detector.ts:234

The new logic order (checking path separators before existsSync) introduces a theoretical regression: if a user has an actual file literally named 'py -3' in the current directory, it would now be incorrectly split into ['py', ['-3']] instead of being recognized as a single file. This is an extremely unlikely scenario in practice.

Suggested fix:

Consider adding a comment documenting this behavioral change, or add a final existsSync check for non-path-like strings before splitting. Given the low probability of this edge case, this is acceptable for now.

🔵 [LOW] Regex patterns use permissive character class for app names

📁 apps/frontend/src/main/python-detector.ts:305

The new regex patterns use [^/]+ and [^\\]+ which allow any characters except path separators in the username and app name positions. While this works correctly and the existing path.normalize() and '..' check provide protection, using a more restrictive character class like [a-zA-Z0-9_\-. ]+ would reduce attack surface.

Suggested fix:

Consider tightening the regex to `/^\/Users\/[a-zA-Z0-9_\-. ]+\/Library\/Application Support\/[a-zA-Z0-9_\-. ]+\/python-venv\/bin\/python\d*(\.\d+)?$/` for defense in depth. The current pattern is acceptable given the existing validation layer.

🔵 [LOW] No unit tests for parsePythonCommand with space-containing paths

📁 apps/frontend/src/main/python-detector.ts:215

The PR adds critical logic for handling paths with spaces, but there are no unit tests specifically testing scenarios like '/Users/user/Library/Application Support/App/python-venv/bin/python'. The existing subprocess-spawn.test.ts tests the spawning but not the path parsing edge cases.

Suggested fix:

Add unit tests for parsePythonCommand covering: 1) paths with spaces that exist, 2) paths with spaces that don't exist yet, 3) simple commands like 'py -3', 4) Windows paths with spaces. This ensures the fix doesn't regress.

This review was generated by Auto Claude.

@abe238
Copy link
Contributor Author

abe238 commented Dec 31, 2025

I have read the CLA Document and I hereby sign the CLA

- Add missing parsePythonCommand import (CodeRabbit critical)
- Consolidate macOS Application Support regex patterns (Gemini)
- Consolidate Windows AppData Roaming regex patterns (Gemini)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@AndyMik90 AndyMik90 self-assigned this Dec 31, 2025
Copy link
Collaborator

@AlexMadera AlexMadera left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

Merge Verdict: ✅ READY TO MERGE

No blocking issues found

Risk Assessment

Factor Level Notes
Complexity Low Based on lines changed
Security Impact Low Based on security findings
Scope Coherence Good Based on structural review

Findings Summary

  • Medium: 1 issue(s)
  • Low: 3 issue(s)

Generated by Auto Claude PR Review

No findings selected for this review.


This review was generated by Auto Claude.

@adryserage
Copy link
Contributor

⚠️ Duplicate PR

This PR appears to be a duplicate of #439, which also fixes Python path handling for paths with spaces.

Recommendation: Close this PR in favor of #439 (created earlier).

Both PRs have the same branch name fix/python-path-spaces and address the same issue.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants