Skip to content

fix(bootstrap): scrub PYTHONHOME/PYTHONPATH before uv so AppImage venv build succeeds (#144, #127) - #158

Merged
debpalash merged 1 commit into
mainfrom
fix/appimage-uv-python-env-leak
May 30, 2026
Merged

fix(bootstrap): scrub PYTHONHOME/PYTHONPATH before uv so AppImage venv build succeeds (#144, #127)#158
debpalash merged 1 commit into
mainfrom
fix/appimage-uv-python-env-leak

Conversation

@debpalash

@debpalash debpalash commented May 30, 2026

Copy link
Copy Markdown
Owner

Problem

On the Linux AppImage, the bundled runtime exports PYTHONHOME / PYTHONPATH (and sometimes LD_LIBRARY_PATH) pointing at the AppImage's own bundled Python. When the first-run bootstrap shells out to uv to create/sync the Python venv, that uv build subprocess inherits those env vars, so the freshly-built managed interpreter resolves its stdlib against the wrong (AppImage) Python and dies with ModuleNotFoundError: No module named 'encodings' while compiling a transitive build dep (e.g. dora-search/demucs).

This surfaces to the user downstream as:

Backend process exited (never started) — no error output captured

— which is exactly what #144 and #127 report on AppImage first-run.

Root cause

The backend spawn in backend.rs already scrubs these vars before launching uvicorn:

cmd.env_remove("PYTHONHOME").env_remove("PYTHONPATH").env_remove("LD_LIBRARY_PATH");

The uv/venv/pip subprocesses in bootstrap.rs need the same scrub. They were doing it, but via five inline copies of the same three env_remove calls — drift-prone (easy for a new uv call site to forget one).

Fix

Cross-platform safety

Safe on every platform: PYTHONHOME / PYTHONPATH / LD_LIBRARY_PATH are normally unset on macOS/Windows, and env_remove on an unset var is a no-op. No change to default behavior off the AppImage; no platform divergence.

Validation

  • cargo check — passes clean.
  • cargo test — 4 bootstrap tests pass, including the new scrub_python_env_removes_bundled_runtime_vars.
  • Compile-validated only: there is no AppImage build in CI to reproduce the original failure end-to-end. The change directly addresses the identified root cause (env leak into uv's build subprocess) and mirrors the proven backend.rs pattern.

Closes the AppImage first-run bootstrap failure behind #144 and #127 (pending reporter confirmation on a build from latest main).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved environment variable isolation during Python dependency installation to prevent system configuration conflicts.
  • Tests

    • Added validation for environment variable handling.

Review Change Stack

…v build succeeds (#144, #127)

On the Linux AppImage, the bundled runtime exports PYTHONHOME / PYTHONPATH
(and sometimes LD_LIBRARY_PATH) pointing at the AppImage's *own* bundled
Python. When first-run bootstrap shells out to `uv` to create/sync the venv,
that build subprocess inherits those vars, so the freshly-built managed
interpreter resolves its stdlib against the wrong (AppImage) Python and dies
with `ModuleNotFoundError: No module named 'encodings'` while compiling a
transitive dep (dora-search/demucs). This surfaces downstream as
"Backend process exited (never started) — no error output captured" (#144).

The backend spawn in backend.rs already scrubs these vars before launching
uvicorn; the uv/venv/pip subprocesses in bootstrap.rs were scrubbing them too
but via five inline copies, which is drift-prone. Factor the scrub into a
single `scrub_python_env(cmd)` helper documenting the #144 root cause, and
apply it at every uv/venv/pip call site (uvicorn import check, repair sync,
venv create, sync, ROCm reinstall). Add a unit test asserting the helper
queues removals for all three vars.

Safe cross-platform: those vars are normally unset on macOS/Windows and
`env_remove` on an unset var is a no-op, so default behavior is unchanged
everywhere. Compile-validated (cargo check + cargo test pass); no AppImage in
CI to reproduce the original failure end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b1b120d-13aa-479e-92ec-f46719738d63

📥 Commits

Reviewing files that changed from the base of the PR and between 8fa54cc and a9c42bb.

📒 Files selected for processing (1)
  • frontend/src-tauri/src/bootstrap.rs

📝 Walkthrough

Walkthrough

This PR consolidates Python environment variable scrubbing in Tauri bootstrap code by introducing a reusable scrub_python_env helper function and applying it to all subprocess construction points that spawn uv, venv, or pip commands, replacing five instances of scattered inline env_remove calls.

Changes

Environment variable scrubbing consolidation

Layer / File(s) Summary
Define scrub_python_env helper
frontend/src-tauri/src/bootstrap.rs
Introduces scrub_python_env(cmd: &mut Command) that removes PYTHONHOME, PYTHONPATH, and LD_LIBRARY_PATH from subprocess environment before running uv/venv/pip-related commands.
Apply scrub_python_env across subprocess commands
frontend/src-tauri/src/bootstrap.rs
Replaces five scattered inline env_remove(...) calls with unified scrub_python_env(&mut cmd) invocations at uvicorn import-check, uv sync repair, uv venv creation, main dependency install, and ROCm torch reinstall points.
Test scrub_python_env behavior
frontend/src-tauri/src/bootstrap.rs
Adds unit test scrub_python_env_removes_bundled_runtime_vars that validates the helper correctly removes the three environment variables as observed via Command::get_envs().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing a helper to scrub Python environment variables before uv so AppImage venv build succeeds.
Description check ✅ Passed The PR description comprehensively covers the problem, root cause, fix details, cross-platform safety, and validation steps, though it lacks the structured template sections like Summary, Changes list, and Type checkboxes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/appimage-uv-python-env-leak

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.

@greptile-apps

greptile-apps Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the AppImage first-run bootstrap failure (#144, #127) where PYTHONHOME/PYTHONPATH/LD_LIBRARY_PATH from the bundled runtime leaked into uv subprocesses, causing ModuleNotFoundError: No module named 'encodings' during venv build.

  • Extracts a scrub_python_env(cmd: &mut Command) helper that calls env_remove for the three vars, replacing five inline copies spread across ensure_venv_ready, and adds a unit test that verifies all three removals are queued.
  • backend.rs already scrubbed these vars before launching uvicorn; this change mirrors that proven pattern for all uv/venv/pip subprocesses in the bootstrap path.

Confidence Score: 4/5

Safe to merge; the change is a straightforward refactor with a new unit test, directly addressing the identified root cause.

The fix is minimal and well-targeted — a private helper replaces five identical inline blocks, and a test verifies the queued removals. The one minor concern is that backend.rs still holds its own inline copy of the same three env_remove calls rather than calling the new helper, leaving a future drift point if the scrub list ever grows.

frontend/src-tauri/src/backend.rs still contains an inline copy of the same three env_remove calls and does not yet use the new helper.

Important Files Changed

Filename Overview
frontend/src-tauri/src/bootstrap.rs Introduces scrub_python_env helper replacing 5 inline env_remove triples; adds unit test. The scrub is applied consistently at all uv/venv/python call sites in ensure_venv_ready. Correct and well-documented.

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(bootstrap): scrub PYTHONHOME/PYTHONP..." | Re-trigger Greptile

Comment on lines +293 to +297
fn scrub_python_env(cmd: &mut Command) {
cmd.env_remove("PYTHONHOME")
.env_remove("PYTHONPATH")
.env_remove("LD_LIBRARY_PATH");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Helper not reused in backend.rs

scrub_python_env is fn (crate-private), so backend.rs retains its own inline scrub at line 259: cmd.env_remove("PYTHONHOME").env_remove("PYTHONPATH").env_remove("LD_LIBRARY_PATH"). If a future ticket adds a fourth variable to the scrub list (e.g. PYTHONEXECUTABLE), the two copies will silently diverge. Making the helper pub(crate) and calling it from backend.rs would eliminate this drift.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

@debpalash
debpalash merged commit b4f238a into main May 30, 2026
15 checks passed
@debpalash
debpalash deleted the fix/appimage-uv-python-env-leak branch June 12, 2026 10:10
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