Skip to content

fix(appimage): cd "$APPDIR" in AppRun before exec to fix sharun preload CWD resolution#2829

Open
staimoorulhassan wants to merge 3 commits into
tinyhumansai:mainfrom
staimoorulhassan:fix/appimage-sharun-paths
Open

fix(appimage): cd "$APPDIR" in AppRun before exec to fix sharun preload CWD resolution#2829
staimoorulhassan wants to merge 3 commits into
tinyhumansai:mainfrom
staimoorulhassan:fix/appimage-sharun-paths

Conversation

@staimoorulhassan
Copy link
Copy Markdown

@staimoorulhassan staimoorulhassan commented May 28, 2026

Summary

  • Adds patch_apprun_sharun_cwd function to scripts/release/strip-appimage-graphics-libs.sh that injects cd "$APPDIR" && before exec "$@" in the AppRun shell script during post-build AppImage repackaging.
  • Wires the new function into strip_one_appimage alongside the existing ensure_sharun_interpreter / rewrite_sharun_lib_path fixes.
  • Fixes AppImages failing to launch when invoked from any directory other than the AppDir itself (e.g. double-click from ~/Downloads).

Problem

OpenHuman_0.56.0_amd64.AppImage fails to launch when the user's CWD is not the AppDir:

ERROR: ld.so: object 'anylinux.so' from --preload cannot be preloaded (cannot open shared object file): ignored.
/tmp/.mount_OpenHuXXXXXX/bin/OpenHuman: error while loading shared libraries: libcef.so: cannot open shared object file: No such file or directory

SHARUN_DIR is set correctly — sharun detects the AppDir fine — but the --preload argument and library search path it hands to ld.so use bare/relative paths that are resolved relative to the process CWD, not SHARUN_DIR. So when CWD ≠ AppDir, anylinux.so and libcef.so are never found.

The failure is purely a CWD mismatch: the app works if and only if the user first cds into the AppDir before launching.

Solution

  • Patch AppRun (the shell script entry point) to cd "$APPDIR" immediately before the exec "$@" call. This guarantees CWD == AppDir by the time sharun runs, making all relative preload/library paths resolve correctly.
  • The patch is applied during the existing strip-appimage-graphics-libs.sh post-build repackaging step — no build system changes needed.
  • Safety guards: only applies when uses_sharun_launcher is true; skips ELF-binary AppRun entries; idempotent (skips if cd "$APPDIR" already present); emits a warning (not a hard failure) if the exec "$@" pattern is not found so the script stays robust to future AppRun layout changes.

The workaround reported in issue #2822:

sed -i 's|^        exec "\$@"|        cd "$APPDIR" \&\& exec "$@"|' squashfs-root/AppRun

This PR generalises that one-liner into the release pipeline.

Submission Checklist

  • N/A: Tests added or updated — this change is a bash release-pipeline script with no Vitest/cargo test harness; the logic is a single sed substitution with an idempotency guard, and correctness is validated by the existing AppImage smoke test in the release process.
  • N/A: Diff coverage ≥ 80% — no TS/Rust production code changed; coverage gate does not apply to scripts/release/ bash scripts.
  • N/A: Coverage matrix updated — behaviour-only change to release pipeline script, no new feature surface.
  • N/A: All affected feature IDs listed — no feature matrix entries affected.
  • N/A: No new external network dependencies — no network calls added.
  • N/A: Manual smoke checklist updated — the fix takes effect automatically during the AppImage repack step; see Impact section.
  • Linked issue closed via Closes #2822 in the Related section.

Impact

  • Linux AppImage users: fixes a launch failure on 0.56.0 that affects all users launching from any directory other than the AppDir (typical user flows: double-click in file manager, shell from ~/Downloads). No impact on macOS, Windows, or .deb users.
  • Release pipeline: strip-appimage-graphics-libs.sh now patches AppRun during its existing repack step. No new tools or dependencies required. Repackaged AppImages are re-signed as before.
  • No performance, security, migration, or compatibility implications beyond fixing the launch failure.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/appimage-sharun-paths
  • Commit SHA: d1341ea

Validation Run

  • N/A: pnpm --filter openhuman-app format:check — only a bash script was changed
  • N/A: pnpm typecheck — only a bash script was changed
  • Focused tests: N/A — no Vitest/cargo tests for scripts/release/ bash scripts
  • N/A: Rust fmt/check (if changed) — no Rust changes
  • N/A: Tauri fmt/check (if changed) — no Tauri changes

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: AppImage now launches correctly from any CWD (e.g. ~/Downloads), not only when CWD == AppDir.
  • User-visible effect: OpenHuman_*.AppImage no longer fails with anylinux.so preload error or missing libcef.so when double-clicked or launched from a shell outside the AppDir.

Parity Contract

  • Legacy behavior preserved: all existing strip-appimage-graphics-libs.sh behavior (graphics lib stripping, sharun interpreter bundling, lib.path rewriting, re-signing) is unchanged.
  • Guard/fallback/dispatch parity checks: uses_sharun_launcher guard ensures non-sharun AppImages are not touched; ELF AppRun guard preserves binary entry points; idempotency guard prevents double-patching.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none
  • Canonical PR: this PR
  • Resolution: N/A

Summary by CodeRabbit

  • Bug Fixes
    • Improved AppImage execution reliability for sharun-based AppImages: the tool now safely ensures the AppImage launches from the correct working directory, avoids partial writes when modifying launch behavior, remains idempotent across runs, emits a warning if it cannot apply the expected fix, and reports whether the launch-file patch was applied during repack.

Review Change Stack

…arun preload CWD resolution (tinyhumansai#2822)

sharun resolves its --preload argument and library search paths relative
to the process CWD rather than the AppDir.  When a user launches
OpenHuman_0.56.0_amd64.AppImage from any directory other than the AppDir
(e.g. double-click from ~/Downloads), ld.so cannot find anylinux.so or
libcef.so even though SHARUN_DIR is set correctly.

Fix: add a new `patch_apprun_sharun_cwd` function to
scripts/release/strip-appimage-graphics-libs.sh that injects
`cd "$APPDIR" && ` before the `exec "$@"` line in the AppRun shell
script during the post-build repackaging step.  This guarantees that
CWD == AppDir by the time sharun runs, so relative preload/library
paths resolve correctly regardless of where the user launches from.

The patch:
- Only applies when the AppImage uses a sharun launcher (detected by
  the existing `uses_sharun_launcher` guard).
- Skips ELF-binary AppRun entries (cannot be sed-patched).
- Is idempotent (skips if `cd "$APPDIR"` is already present).
- Emits a clear warning if the exec line pattern is not found rather
  than silently missing the fix.
- Triggers a repack of the AppImage (same path as the loader/lib.path
  fixes) and is re-signed alongside other mutations.

Verified workaround from the bug report:
  sed -i 's|^        exec "\$@"|        cd "$APPDIR" \&\& exec "$@"|' squashfs-root/AppRun

This commit generalises that one-liner into the release pipeline so
future releases ship with the fix pre-applied.
@staimoorulhassan staimoorulhassan requested a review from a team May 28, 2026 08:34
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 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: 61a227a7-4d6c-491a-9c75-7794cabf1765

📥 Commits

Reviewing files that changed from the base of the PR and between d1341ea and 0438d08.

📒 Files selected for processing (1)
  • scripts/release/strip-appimage-graphics-libs.sh

📝 Walkthrough

Walkthrough

Adds an idempotent AppRun patch for sharun-based AppImages: new patch_apprun_sharun_cwd injects cd "$APPDIR" && before exec "$@" in shell AppRun scripts; strip_one_appimage tracks and reports the patch via a new patched_apprun flag and updated early-exit/repack logic.

Changes

AppRun CWD Patching for Sharun

Layer / File(s) Summary
patch_apprun_sharun_cwd function
scripts/release/strip-appimage-graphics-libs.sh
New function detects sharun usage, validates AppRun is a non-ELF shell script, checks for prior patching to remain idempotent, rewrites the final exec "$@" line via a temporary file for atomic update, and returns success or warns/fails if the expected pattern is not found.
Integration into strip_one_appimage
scripts/release/strip-appimage-graphics-libs.sh
Adds patched_apprun flag, invokes patch_apprun_sharun_cwd and records its result, extends the early “leave unchanged” condition to consider patched_apprun, and updates the repack log line to include patched AppRun=$patched_apprun.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • graycyrus
  • senamakel

Poem

🐰 I hopped into AppRun's nest,
Poked a cd so libs find their rest,
Sharun now walks to APPDIR's beat,
Execs succeed — no missing seat,
a carrot for the CI run! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 accurately describes the main change: adding cd "$APPDIR" before exec in AppRun to fix sharun CWD-based preload resolution.
Linked Issues check ✅ Passed The PR implements the verified workaround from issue #2822 by adding patch_apprun_sharun_cwd to inject cd "$APPDIR" && before exec "$@", directly addressing the CWD-relative preload resolution failure.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the sharun CWD issue: the new patch_apprun_sharun_cwd function and integration into strip_one_appimage are directly related to issue #2822 objectives.

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


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

🤖 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 `@scripts/release/strip-appimage-graphics-libs.sh`:
- Around line 369-372: The current idempotency guard uses a too-broad grep
('cd.*"$APPDIR"') against the AppRun file (variable apprun), which can match
comments or unrelated lines and cause false positives leaving exec "$@"
unpatched; tighten the check to look for an exact cd invocation (e.g. anchored
line allowing only whitespace, optional sudo, and optional && or || constructs
around cd "$APPDIR") so you only treat a file as already patched when a real cd
"$APPDIR" command is present, update the grep/regex used in the block that
references apprun and replicate the same stricter check at the analogous
location referenced in the comment (the occurrence around line 385) so both
idempotency and post-write checks are robust.
🪄 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: 0417ed6f-d418-444d-a56d-5f1c2b17f7a3

📥 Commits

Reviewing files that changed from the base of the PR and between 145e768 and d1341ea.

📒 Files selected for processing (1)
  • scripts/release/strip-appimage-graphics-libs.sh

Comment thread scripts/release/strip-appimage-graphics-libs.sh
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 28, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Summary

This PR fixes a real problem — AppImage failing to launch from directories other than the AppDir. The solution (injecting cd "$APPDIR" in AppRun before exec) is sound and well-implemented.

However, CodeRabbit flagged a correctness issue with the grep patterns used for idempotency and validation. The patterns are too loose and could match false positives (e.g., comments containing the string). This needs to be tightened.

Key Issues

[major] lines 369, 385: Idempotency and post-write grep patterns too loose

The pattern cd.*"\$APPDIR" can match comments, unrelated lines, or incomplete commands. If someone adds a comment like # cd "$APPDIR" to AppRun, the script will incorrectly think it's already patched and skip the fix. Similarly, the post-write validation could pass even if the sed only partially matched.

Suggestion: Tighten to match the complete command:

  • Idempotency check: grep -Eq '^[[:space:]]*cd[[:space:]]+"\$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"\$@"[[:space:]]*$' — only match if the exact pattern exists
  • sed pattern: anchor to end-of-line: 's|^\([[:space:]]*\)exec "\$@"$|\1cd "$APPDIR" \&\& exec "\$@"|' — avoid issues with trailing whitespace
  • Post-write validation: use the same stricter grep

[minor] line 363: Shellcheck warning (SC2016) — expressions don't expand in single quotes

Using single quotes in the comment means the $APPDIR example doesn't render. Minor style issue, but worth fixing to avoid confusing future readers.

CI Status

One check failing: PR Submission Checklist — the N/A items need to be explicitly checked with [x], not just annotated in text. The CI is right to fail here; please update the checklist boxes even for N/A items.

Process

  1. Tighten the grep patterns as suggested above
  2. Check all PR Submission Checklist items (even N/A ones need [x])
  3. Re-run the tests
  4. I'll re-review and approve once both are fixed

Comment thread scripts/release/strip-appimage-graphics-libs.sh
# typically have a line of the form (possibly with leading whitespace):
# exec "$@"
# Patch it to:
# cd "$APPDIR" && exec "$@"
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.

[major] The sed pattern should anchor to end-of-line to avoid partial matches with trailing whitespace:

's|^\([[:space:]]*\)exec "\$@"$|\1cd "$APPDIR" \&\& exec "\$@"|'

Without the $, sed could match and partially corrupt lines with extra content afterward.

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.

Fixed in 0438d08. Anchored the sed pattern with [[:space:]]*$ so an exec line with trailing content (e.g. exec "$@" >> /tmp/log 2>&1) is left untouched and the warning branch fires, rather than partially absorbing the trailing tokens into the new cd && exec sequence. Verified with a trailing-redirect fixture.

tmp_apprun="$(mktemp)"
if sed 's|^\([[:space:]]*\)exec "\$@"|\1cd "$APPDIR" \&\& exec "$@"|' \
"$apprun" > "$tmp_apprun" \
&& grep -q 'cd.*"\$APPDIR"' "$tmp_apprun"; then
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.

[major] Same issue as line 369 — use the stricter grep pattern here too:

grep -Eq '^[[:space:]]*cd[[:space:]]+"\$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"\$@"[[:space:]]*$'

This post-write validation must match the actual patched pattern, not a loose substring.

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.

Fixed in 0438d08. Post-write validation now reuses the same $patched_line_re variable as the idempotency check, so we only consider the patch successful when the new file actually contains the canonical patched line.

@sanil-23 sanil-23 self-assigned this May 28, 2026
sanil-23 and others added 2 commits May 28, 2026 16:15
…pattern

Address review feedback on tinyhumansai#2829 from @graycyrus and CodeRabbit:

1. Idempotency guard used a loose substring grep (cd.*"$APPDIR") that
   could false-positive on comments like '# cd "$APPDIR"' or unrelated
   lines, leaving the real exec "$@" line unpatched. Tighten to an
   anchored regex matching the full patched line:
     ^[[:space:]]*cd[[:space:]]+"$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"$@"[[:space:]]*$
   so only a genuine patched-by-us line trips the guard.

2. sed substitution lacked an end-of-line anchor, so an exec line with
   trailing content (extra args, redirections, comments) would have been
   partially rewritten with the trailing content silently absorbed into
   the cd && exec sequence. Anchor the pattern to $ so we only rewrite a
   clean `exec "$@"` line; otherwise the warning branch fires and the
   AppRun is left untouched.

3. Post-write validation now uses the same stricter regex so success is
   only declared when the new file actually contains the expected line.

Co-Authored-By: Claude <noreply@anthropic.com>
@sanil-23
Copy link
Copy Markdown
Contributor

Pushed 0438d08 addressing both reviews:

  • Idempotency / sed / post-write grep: replaced the loose cd.*"$APPDIR" pattern with the anchored regex ^[[:space:]]*cd[[:space:]]+"\$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"\$@"[[:space:]]*$ for both the idempotency guard and the post-write validation, and added an end-of-line anchor to the sed substitution so trailing content can't be partially absorbed.
  • PR Submission Checklist (CI): all N/A items in the checklist and Validation Run sections are now explicitly checked with [x].

Verified the new logic locally with four fixture AppRun files (clean exec, commented # cd "$APPDIR", trailing redirects, already-patched). The shellcheck SC2016 hit at line 363 is in the function-header comment block, not in code — single-quoting the literal cd "$APPDIR" is intentional there (showing the bash text as-written). Happy to fix that as a follow-up if you'd prefer; it's just doc-comment content.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Good follow-up commit. I've reviewed your changes and all three prior findings have been properly addressed:

[major] Grep pattern fix (line 407): Tightened to ^[[:space:]]*cd[[:space:]]+"\$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"\$@"[[:space:]]*$ — exact match, no false-positives on comments.

[major] sed anchoring (line 419): Pattern now anchors to end-of-line (exec "\$@"$) to avoid partial matches.

[major] Post-write validation (line 428): Uses the same strict grep pattern to ensure the patch actually applied.

[admin] Submission Checklist: All N/A items now properly checked with [x].

Code review

Logic is sound:

  • Idempotency guard prevents re-patching (critical for safety)
  • Temp file + mv avoids truncation on failure
  • Uses sharun launcher check + ELF binary guard to avoid touching unrelated AppRun files
  • Error message + return code communicate success/failure clearly
  • Integration with strip_one_appimage is clean

All fixes verified against prior review requests.

CI Status

One check is failing: Coverage Gate (diff-cover ≥ 80%). This is expected — bash script changes don't meet coverage gates designed for TypeScript/Rust. Once pending tests complete and this false-positive is resolved (or explicitly skipped for scripts/release/), I'll come back and approve.

Let me know if you need help with the coverage gate issue or if there's a way to exempt bash release scripts from that check.

Copy link
Copy Markdown
Contributor

@sanil-23 sanil-23 left a comment

Choose a reason for hiding this comment

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

Approving from shepherd queue (round 2). All CI green or known flakes re-running; pnpm review fix round complete. Happy to merge once required reviewers concur.

@sanil-23 sanil-23 requested a review from graycyrus May 28, 2026 17:37
@sanil-23
Copy link
Copy Markdown
Contributor

Hi @graycyrus — your 14:34Z comment said "Good follow-up commit. I've reviewed your changes and all three prior findings have been properly addressed" on this PR (✓ grep pattern, ✓ sed anchoring, ✓ post-write validation). Could you flip the review to APPROVE so this can merge? CI is at 30 success / 0 fail on head 0438d08, CodeRabbit APPROVED at 14:22Z. The only thing blocking merge is your prior CHANGES_REQUESTED still being sticky.

Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Prior changes all addressed — grep patterns are now tight, sed is anchored, validation is strict, and PR Submission Checklist properly filled. CI is green across the board. This is good to merge.

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.

AppImage 0.56.0 fails to launch: sharun resolves preload/library paths relative to CWD, not AppDir

3 participants