Skip to content

fix: sanitize AppImage environment before opening URLs#710

Merged
skevetter merged 3 commits intomainfrom
investigate-issue-127
Apr 12, 2026
Merged

fix: sanitize AppImage environment before opening URLs#710
skevetter merged 3 commits intomainfrom
investigate-issue-127

Conversation

@skevetter
Copy link
Copy Markdown
Owner

@skevetter skevetter commented Apr 11, 2026

Summary

Fixes #127

  • Consolidates pkg/open.Run(), which detects AppImage environments and sanitizes the process environment before spawning xdg-open
  • Strips LD_LIBRARY_PATH, LD_PRELOAD, APPDIR, and other AppImage-injected variables that cause library conflicts for child processes
  • Uses /usr/bin/xdg-open by absolute path to bypass Tauri's bundled wrapper

Background

When running inside a Linux AppImage, the AppRun script prepends bundled library paths to LD_LIBRARY_PATH. Child processes like xdg-open and gio then load these bundled libraries instead of the system ones, causing symbol lookup errors (e.g. undefined symbol: g_unix_mount_entry_get_options). This prevents JetBrains Gateway and other applications from opening via custom URL schemes.

References:

Summary by CodeRabbit

  • Bug Fixes

    • Improved URL opening reliability for AppImage-based Linux distributions with environment variable sanitization.
  • Refactor

    • Consolidated URL opening functionality by replacing external dependency with internal implementation across IDE integrations and authentication flows.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 339fd5c9-810c-42c5-a5be-36f5f8c3ea4e

📥 Commits

Reviewing files that changed from the base of the PR and between 7a02738 and 820648d.

📒 Files selected for processing (11)
  • cmd/pro/start.go
  • pkg/client/clientimplementation/daemonclient/client.go
  • pkg/ide/jetbrains/generic.go
  • pkg/ide/opener/opener.go
  • pkg/ide/vscode/open.go
  • pkg/ide/zed/zed.go
  • pkg/ide/zed/zed_linux.go
  • pkg/open/appimage_linux.go
  • pkg/open/appimage_other.go
  • pkg/open/open.go
  • pkg/platform/client/client.go
✅ Files skipped from review due to trivial changes (7)
  • pkg/ide/opener/opener.go
  • pkg/ide/vscode/open.go
  • pkg/ide/zed/zed.go
  • pkg/ide/jetbrains/generic.go
  • pkg/client/clientimplementation/daemonclient/client.go
  • cmd/pro/start.go
  • pkg/open/appimage_other.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/platform/client/client.go
  • pkg/ide/zed/zed_linux.go
  • pkg/open/appimage_linux.go

📝 Walkthrough

Walkthrough

The PR replaces the external github.com/skratchdot/open-golang/open package with an internal github.com/skevetter/devpod/pkg/open wrapper across the codebase. The internal wrapper includes AppImage-specific environment sanitization logic on Linux to address URL opening failures in AppImage builds by removing interfering environment variables before invoking system handlers.

Changes

Cohort / File(s) Summary
IDE Open Call Updates
cmd/pro/start.go, pkg/client/clientimplementation/daemonclient/client.go, pkg/ide/jetbrains/generic.go, pkg/ide/vscode/open.go, pkg/ide/zed/zed.go, pkg/platform/client/client.go, pkg/ide/opener/opener.go
Replaced external open.Run() calls from github.com/skratchdot/open-golang/open with devpodopen.Run() from the internal package; imports updated accordingly with no change to surrounding control flow.
Zed Linux-Specific Opener
pkg/ide/zed/zed_linux.go
Replaced direct xdg-open invocation via exec.Command() with devpodopen.Run(), removing captured output and detailed debug logging but preserving error handling.
Internal Open Package: Core Logic
pkg/open/open.go
Added exported Run() function that selectively invokes AppImage-specific openURLSanitized() when running as AppImage, otherwise falls back to standard open.Run(); updated error propagation in tryOpen to wrap and report opener failures.
Internal Open Package: AppImage Linux Implementation
pkg/open/appimage_linux.go
Added AppImage detection via isAppImage() and sanitized URL opener openURLSanitized() that removes AppImage-injected environment variables (APPDIR, APPIMAGE, ARGV0, OWD, APPIMAGE_BUNDLE_XDG_OPEN) and clears LD_LIBRARY_PATH and LD_PRELOAD before launching xdg-open.
Internal Open Package: Non-Linux Stub
pkg/open/appimage_other.go
Build-gated stubs for non-Linux platforms; isAppImage() returns false and openURLSanitized() returns a not-available error.

Sequence Diagram

sequenceDiagram
    participant Caller as IDE/CLI Caller
    participant DevPodOpen as devpodopen.Run()
    participant IsAppImage as isAppImage()
    participant Sanitize as sanitizedEnv()
    participant OpenURL as openURLSanitized(url)
    participant XdgOpen as xdg-open (system)
    participant StdOpen as open.Run() (stdlib)

    Caller->>DevPodOpen: Run(url)
    DevPodOpen->>IsAppImage: isAppImage()?
    
    alt Running as AppImage
        IsAppImage-->>DevPodOpen: true
        DevPodOpen->>OpenURL: openURLSanitized(url)
        OpenURL->>Sanitize: sanitizedEnv()
        Sanitize-->>OpenURL: filtered env (no APPIMAGE vars)
        OpenURL->>XdgOpen: exec with sanitized env
        XdgOpen-->>OpenURL: success/error
        OpenURL-->>DevPodOpen: error or nil
    else Not AppImage
        IsAppImage-->>DevPodOpen: false
        DevPodOpen->>StdOpen: open.Run(url)
        StdOpen->>XdgOpen: standard system handler
        XdgOpen-->>StdOpen: result
        StdOpen-->>DevPodOpen: error or nil
    end
    
    DevPodOpen-->>Caller: return error (wrapped if any)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: sanitize AppImage environment before opening URLs' directly and accurately describes the main change: consolidating URL opening logic and sanitizing AppImage environment variables before spawning handlers.
Linked Issues check ✅ Passed The PR successfully addresses issue #127 by implementing AppImage environment sanitization, stripping AppImage-injected variables that cause library conflicts, and using absolute path to xdg-open to bypass Tauri's bundled wrapper.
Out of Scope Changes check ✅ Passed All changes are in-scope: they consolidate URL-opening across nine files by replacing the external open-golang package with the internal devpod/pkg/open wrapper, and implement AppImage-specific environment sanitization to fix the reported issue.

✏️ 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 investigate-issue-127

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
Copy Markdown

@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

🧹 Nitpick comments (1)
pkg/open/appimage_other.go (1)

9-10: Prefer returning an error instead of panicking in non-Linux stub.

This path should be unreachable, but panic makes accidental calls crash the process unnecessarily.

♻️ Suggested change
+import "errors"
+
 func openURLSanitized(_ string) error {
-	panic("openURLSanitized is only available on Linux")
+	return errors.New("openURLSanitized is only available on Linux")
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/open/appimage_other.go` around lines 9 - 10, The non-Linux stub
openURLSanitized should return an error instead of panicking; change the
implementation of openURLSanitized to return a descriptive error (e.g., using
errors.New or fmt.Errorf) stating that openURLSanitized is only available on
Linux so accidental calls don't crash the process, and ensure callers receive
that error instead of causing a panic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/open/open.go`:
- Line 33: tryOpen is swallowing opener errors which leads Open/Run to log
"opened url" on failures; update tryOpen (and its callers Open/Run) so any error
returned by the opener is propagated upward instead of being dropped: locate
tryOpen, ensure it returns the opener error instead of returning nil on failure,
and adjust Open/Run callers to check and return that error (and only log "opened
url" after confirming no error) so failures stop retries and are reported
correctly.

---

Nitpick comments:
In `@pkg/open/appimage_other.go`:
- Around line 9-10: The non-Linux stub openURLSanitized should return an error
instead of panicking; change the implementation of openURLSanitized to return a
descriptive error (e.g., using errors.New or fmt.Errorf) stating that
openURLSanitized is only available on Linux so accidental calls don't crash the
process, and ensure callers receive that error instead of causing a panic.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fce1789f-d334-48dd-997f-1f81d8ba36bd

📥 Commits

Reviewing files that changed from the base of the PR and between 3cc1d02 and 53ea2d7.

📒 Files selected for processing (11)
  • cmd/pro/start.go
  • cmd/up.go
  • pkg/client/clientimplementation/daemonclient/client.go
  • pkg/ide/jetbrains/generic.go
  • pkg/ide/vscode/open.go
  • pkg/ide/zed/zed.go
  • pkg/ide/zed/zed_linux.go
  • pkg/open/appimage_linux.go
  • pkg/open/appimage_other.go
  • pkg/open/open.go
  • pkg/platform/client/client.go

Comment thread pkg/open/open.go
@github-actions github-actions bot added size/l and removed size/m labels Apr 11, 2026
@coderabbitai coderabbitai bot added the size/m label Apr 11, 2026
Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
pkg/open/open.go (1)

33-36: ⚠️ Potential issue | 🟠 Major

Return opener failures instead of retrying them forever.

Line 33 now gets the wrapped open url: error from tryOpen, but this loop still treats it like a transient reachability failure. If xdg-open keeps failing, Open will spin until the context expires and then return nil, so callers still can't tell that nothing was opened. Please stop retrying once the failure is coming from the opener itself.

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

In `@pkg/open/open.go` around lines 33 - 36, The loop in Open retries forever even
when tryOpen returns an opener failure; change Open so that when tryOpen(ctx,
url, Run, log) returns a non-nil error that indicates the opener itself failed
(the wrapped "open url:" error from tryOpen), Open returns that error
immediately instead of continuing to retry until context deadline; locate the
retry loop in Open and add a condition to detect the opener error returned by
tryOpen and return it directly (do not swallow and continue).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@pkg/open/open.go`:
- Around line 33-36: The loop in Open retries forever even when tryOpen returns
an opener failure; change Open so that when tryOpen(ctx, url, Run, log) returns
a non-nil error that indicates the opener itself failed (the wrapped "open url:"
error from tryOpen), Open returns that error immediately instead of continuing
to retry until context deadline; locate the retry loop in Open and add a
condition to detect the opener error returned by tryOpen and return it directly
(do not swallow and continue).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 89d1486e-1be6-46ff-a76d-0e1f7b578d10

📥 Commits

Reviewing files that changed from the base of the PR and between 53ea2d7 and 7a02738.

📒 Files selected for processing (2)
  • pkg/open/appimage_other.go
  • pkg/open/open.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/open/appimage_other.go

@skevetter skevetter marked this pull request as ready for review April 12, 2026 02:34
When running inside a Linux AppImage, the AppRun script prepends bundled
library paths to LD_LIBRARY_PATH. Child processes like xdg-open and gio
then load these bundled libraries instead of the system ones, causing
symbol lookup errors (e.g. "undefined symbol: g_unix_mount_entry_get_options").

This centralizes all URL-opening through pkg/open.Run(), which detects
the AppImage environment and strips injected variables (LD_LIBRARY_PATH,
LD_PRELOAD, APPDIR, etc.) before spawning xdg-open. It also uses
/usr/bin/xdg-open by absolute path to bypass Tauri's bundled wrapper.

References:
- AppImage/AppImageKit#396
- AppImage/AppImageKit#616
- tauri-apps/tauri#10617
@skevetter skevetter force-pushed the investigate-issue-127 branch from 7a02738 to 820648d Compare April 12, 2026 06:08
@github-actions github-actions bot removed the size/m label Apr 12, 2026
@skevetter skevetter merged commit 702c227 into main Apr 12, 2026
41 checks passed
@skevetter skevetter deleted the investigate-issue-127 branch April 12, 2026 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JetBrains Gateway does not open (AppImage builds only)

1 participant