Skip to content

fix(bootstrap): surface why the backend "never started" (refs #144, #127) - #148

Merged
debpalash merged 2 commits into
mainfrom
fix/bootstrap-surface-spawn-error
May 29, 2026
Merged

fix(bootstrap): surface why the backend "never started" (refs #144, #127)#148
debpalash merged 2 commits into
mainfrom
fix/bootstrap-surface-spawn-error

Conversation

@debpalash

@debpalash debpalash commented May 29, 2026

Copy link
Copy Markdown
Owner

AppImage users get "Backend process exited (never started) — no error output captured" (#144, #127) with nothing actionable.

Root gap

When Command::spawn() of the venv Python fails — the common Linux/AppImage case (the bundled interpreter can't exec: missing system lib, stale venv, arch mismatch) — spawn_backend logged the OS error but returned None silently, so the bootstrap surfaced the useless "no error output captured."

Fix

On spawn failure, write a diagnostic to backend_err.log (which the bootstrap's read_error_log_tail already reads): the interpreter path, whether it exists on disk, the real OS error, and an actionable hint ("Clean & Retry / run the AppImage from a terminal to see the loader error"). The dead-end becomes the actual launch error.

Scope / honesty

This makes the failure diagnosable — it surfaces why the backend won't start. It doesn't blindly guess the specific AppImage root cause (which needs that now-visible error). Once a reporter shares the surfaced message, the underlying cause routes to a targeted fix. Same "errors must be visible" principle as plan-04, applied to the Tauri bootstrap.

Tests

Pure message builder unit-tested (spawn_failure_diagnostic); cargo test + cargo check clean. (Full AppImage repro isn't possible in CI.)

Refs #144, #127.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved startup error diagnostics when the bundled backend fails to launch, providing a human-readable message with interpreter path, OS error text, and platform-specific troubleshooting hints; this diagnostic is logged so existing log-tail mechanisms surface the real execution error.
  • Tests

    • Added a unit test to verify the diagnostic message includes the interpreter path, OS error text, and actionable hint.

Review Change Stack

AppImage users hit "Backend process exited (never started) — no error output
captured" with nothing to act on. Root gap: when `Command::spawn()` of the
venv Python fails (the common Linux/AppImage case — interpreter can't exec,
missing system lib, stale venv), spawn_backend logged the OS error but returned
None silently, so the bootstrap reported "no error output captured".

Now the spawn failure writes a diagnostic (the interpreter path, whether it
exists on disk, the OS error, and an actionable "Clean & Retry / run from a
terminal" hint) to backend_err.log, which the bootstrap's read_error_log_tail
already surfaces. The "no output" dead-end becomes the real launch error.

This makes #144/#127 diagnosable (the underlying AppImage cause then routes from
the now-visible error). Pure message builder is unit-tested; cargo test +
cargo check clean.

Refs #144, #127.

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

coderabbitai Bot commented May 29, 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: 6500ba82-98fe-4ae1-a03b-1cf83f481e24

📥 Commits

Reviewing files that changed from the base of the PR and between 18d49f7 and 13d6015.

📒 Files selected for processing (1)
  • frontend/src-tauri/src/backend.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src-tauri/src/backend.rs

📝 Walkthrough

Walkthrough

The PR enhances backend spawn error handling by introducing a spawn_failure_diagnostic helper that formats detailed error messages when the bundled Python interpreter fails to spawn. The diagnostic includes the interpreter path, disk presence check, OS error text, and a Linux/AppImage-specific recovery hint, which is logged and persisted to backend_err.log for visibility via existing log-tail logic.

Changes

Backend spawn failure diagnostic

Layer / File(s) Summary
Diagnostic helper implementation and integration
frontend/src-tauri/src/backend.rs
Adds std::path::Path import, introduces spawn_failure_diagnostic(python, err) helper that formats interpreter path, existence flag, OS error, and platform-specific hints. Integrates into spawn_backend error handling to log and write diagnostics to backend_err.log. Includes unit tests validating diagnostic content includes interpreter path, OS error message, existence check, and actionable hint.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the root problem, the fix, scope, and testing approach thoroughly, though it omits the required description template sections (Type, Testing checklist, Release cadence confirmation). Complete the template by selecting a Type checkbox (appears to be a bug fix), confirming testing steps, and confirming this doesn't affect release cadence or requires pre-rc1 landing.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: improving error diagnostics for backend startup failures on AppImage/Linux, which is the core purpose of this PR.
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/bootstrap-surface-spawn-error

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 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Surfaces the real OS error when Command::spawn() of the venv Python fails — the root cause of the cryptic "Backend process exited (never started) — no error output captured" seen by AppImage users (issues #144, #127). The fix writes a structured diagnostic (interpreter path, disk-presence check, OS error, actionable hint) to backend_err.log, which read_error_log_tail already reads for display.

  • Adds spawn_failure_diagnostic, a pure message-builder with platform-conditional hints (cfg!(target_os)) for Linux, macOS, and Windows.
  • Writes the diagnostic to backend_err.log in the spawn-failure branch, and includes a unit test for the message structure.

Confidence Score: 5/5

Safe to merge — the change is additive, only affects the spawn-failure error path, and cannot regress the happy path.

The only code touched is in the Err branch of Command::spawn(), which previously just logged and returned None. Writing a diagnostic to backend_err.log in that branch is a best-effort improvement; even if the write fails the function still returns None and the caller's existing error handling is unchanged. Platform-specific hints are correctly gated with cfg!(target_os), addressing the earlier review concern.

No files require special attention.

Important Files Changed

Filename Overview
frontend/src-tauri/src/backend.rs Adds spawn_failure_diagnostic helper and writes its output to backend_err.log on Command::spawn() failure; adds platform-conditional OS hints and a unit test. Fix is well-scoped and correctly addresses issues #144/#127.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[spawn_backend called] --> B[backend_log_path - create dir]
    B --> C[fs::File::create backend_err.log truncates file]
    C --> D[ensure_venv_ready - get python path]
    D --> E{Command::spawn}
    E -->|Ok - child| F[Spawn stderr pipe thread writes to err_log_file]
    F --> G[Return Some child]
    E -->|Err - e| H[spawn_failure_diagnostic python path + exists + OS error + os_hint]
    H --> I[log::error diag]
    I --> J[fs::write backend_err.log diag]
    J --> K[return None - err_log_file dropped]
    K --> L[Bootstrap calls read_error_log_tail shows diagnostic to user]
Loading

Fix All in Claude Code

Reviews (2): Last reviewed commit: "fix(bootstrap): platform-specific spawn-..." | Re-trigger Greptile

Comment thread frontend/src-tauri/src/backend.rs Outdated
Comment on lines +149 to +152
On Linux (especially the AppImage) this usually means the bundled venv \
Python can't execute — a missing system library or a stale/incomplete \
venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \
AppImage from a terminal to see the dynamic-loader error.",

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 The diagnostic hint is tightly coupled to Linux/AppImage terminology. On macOS or Windows a user will see "run the AppImage from a terminal to see the dynamic-loader error" — which is meaningless (there is no AppImage and no dynamic-loader to inspect). The "Clean & Retry" part is universally actionable, but the trailing sentence actively misleads non-Linux users. A platform-conditional hint would keep the message accurate on every OS.

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

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed — the OS-specific tail is now chosen by build target via cfg!(target_os): the AppImage/dynamic-loader wording only on Linux, a venv/quarantine hint on macOS, and a missing-Python/antivirus hint on Windows. The 'Clean & Retry' line stays universal.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src-tauri/src/backend.rs`:
- Around line 145-153: The diagnostic currently logs the full interpreter path
via the python variable when building diag; sanitize any absolute user-home
prefixes before formatting or persisting diagnostics: detect the current user's
home directory (e.g., via dirs::home_dir() or
std::env::var("HOME")/USERPROFILE), and if the python path starts with that home
prefix, replace that prefix with a redacted token like "~" or "[REDACTED_HOME]"
before inserting into the formatted message; apply the same sanitization helper
to all other spawn diagnostic strings (including the occurrences referenced
around the python usage and the additional cases at the later block noted for
lines ~245-247) so no absolute /Users/... or C:\Users\... segments are logged or
persisted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f44f3781-d1fd-4a48-beea-d2a532a856b9

📥 Commits

Reviewing files that changed from the base of the PR and between ee67130 and 18d49f7.

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

Comment on lines +145 to +153
"Failed to launch the backend process.\n\
Tried to run: {}\n\
Interpreter present on disk: {}\n\
OS error: {}\n\n\
On Linux (especially the AppImage) this usually means the bundled venv \
Python can't execute — a missing system library or a stale/incomplete \
venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \
AppImage from a terminal to see the dynamic-loader error.",
python.display(),

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Redact user-home prefixes before logging/persisting spawn diagnostics.

The diagnostic now logs and writes the full interpreter path; that can include absolute user-home paths and violates policy. Please sanitize python before formatting diag.

Suggested patch
+fn redact_user_home_path(path: &Path) -> String {
+    let raw = path.to_string_lossy().to_string();
+
+    #[cfg(target_os = "macos")]
+    if let Ok(home) = std::env::var("HOME") {
+        let prefix = format!("{}/", home);
+        if raw.starts_with(&prefix) {
+            return raw.replacen(&home, "~", 1);
+        }
+    }
+
+    #[cfg(target_os = "windows")]
+    if let Ok(home) = std::env::var("USERPROFILE") {
+        if raw.starts_with(&home) {
+            return raw.replacen(&home, "%USERPROFILE%", 1);
+        }
+    }
+
+    raw
+}
+
 fn spawn_failure_diagnostic(python: &Path, err: &std::io::Error) -> String {
+    let redacted_python = redact_user_home_path(python);
     format!(
         "Failed to launch the backend process.\n\
          Tried to run: {}\n\
          Interpreter present on disk: {}\n\
          OS error: {}\n\n\
          On Linux (especially the AppImage) this usually means the bundled venv \
          Python can't execute — a missing system library or a stale/incomplete \
          venv. Use \"Clean & Retry\" to rebuild it; if it persists, run the \
          AppImage from a terminal to see the dynamic-loader error.",
-        python.display(),
+        redacted_python,
         python.exists(),
         err,
     )
 }

As per coding guidelines, "Flag any code that persists or logs values matching TOKEN/KEY/SECRET or absolute user home paths (/Users//, C:\Users\\)."

Also applies to: 245-247

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src-tauri/src/backend.rs` around lines 145 - 153, The diagnostic
currently logs the full interpreter path via the python variable when building
diag; sanitize any absolute user-home prefixes before formatting or persisting
diagnostics: detect the current user's home directory (e.g., via
dirs::home_dir() or std::env::var("HOME")/USERPROFILE), and if the python path
starts with that home prefix, replace that prefix with a redacted token like "~"
or "[REDACTED_HOME]" before inserting into the formatted message; apply the same
sanitization helper to all other spawn diagnostic strings (including the
occurrences referenced around the python usage and the additional cases at the
later block noted for lines ~245-247) so no absolute /Users/... or C:\Users\...
segments are logged or persisted.

The diagnostic tail said "run the AppImage from a terminal… dynamic-loader
error" — meaningless on macOS/Windows (spawn can fail on any OS). Pick the hint
by build-target OS via cfg!: AppImage/loader wording on Linux, venv/quarantine
on macOS, missing-Python/AV-block on Windows. "Clean & Retry" stays universal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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