-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Description
Description
The OpenCode Desktop app (Tauri-based) gets stuck on the "Starting server..." loading screen on macOS. The root cause is the -i (interactive) flag used when spawning the sidecar CLI process.
Root Cause
In packages/desktop/src-tauri/src/lib.rs (around line 134-145), the sidecar is spawned via:
app.shell().command(&shell)
.args(["-il", "-c", &format!("\"{}\" serve --port={}", sidecar.display(), port)])The -i flag forces interactive mode, which causes zsh to:
- Load
~/.zshrc(oh-my-zsh, themes, plugins) - Initialize ZLE (Zsh Line Editor) hooks
- Set up prompt rendering, syntax highlighting, autosuggestions
Since the desktop app has no TTY (it's a GUI process), ZLE-dependent plugins like zsh-syntax-highlighting and zsh-autosuggestions hang indefinitely during initialization — they expect terminal I/O that doesn't exist.
Reproduction
# This works (non-interactive):
zsh -c "/Applications/OpenCode.app/Contents/MacOS/opencode-cli debug config"
# This works (login only, no interactive):
zsh -lc "/Applications/OpenCode.app/Contents/MacOS/opencode-cli debug config"
# This HANGS (interactive + login):
zsh -il -c "/Applications/OpenCode.app/Contents/MacOS/opencode-cli debug config"Environment
- OS: macOS Sequoia (Apple Silicon)
- OpenCode Desktop: v1.2.13
- Shell:
/bin/zshwith oh-my-zsh +zsh-syntax-highlighting+zsh-autosuggestions(extremely common setup) - Theme: agnoster
Desktop App Logs (failing)
INFO opencode_lib: Initializing app
INFO opencode_lib: Main and loading windows created
INFO opencode_lib: Setting up server connection
INFO opencode_lib::cli: CLI is up to date, skipping sync
← Stops here. Never reaches "Attempting server connection"
Suggested Fix
Change the shell invocation from -il to -lc:
// Before (hangs when user has ZLE plugins):
.args(["-il", "-c", &format!("\"{}\" serve --port={}", sidecar.display(), port)])
// After (login shell for PATH, but no interactive mode):
.args(["-lc", &format!("\"{}\" serve --port={}", sidecar.display(), port)])The -l (login) flag is sufficient to load ~/.zprofile for PATH setup (Homebrew, nvm, etc.). The -i flag is unnecessary for a non-interactive subprocess and actively harmful in a no-TTY environment.
Related Issues
- Desktop sidecar spawn can time out on macOS with interactive shell startup #13926 — Same symptom (CLOSED, but the
-iflag is still present in v1.2.13) - Desktop app fails to start on Linux/Wayland - 'open terminal failed: not a terminal' #9505 — Linux/Wayland: "open terminal failed: not a terminal" (same root cause)
- Opencode Desktop error with nushell as default shell #8716 — nushell as default shell causes spawn failure (same
$SHELL -il -cpattern) - [GUI - Macos] An error occurred while loading the application #13597 — macOS: "Health check timed out" (same symptom)
Workaround
Users can add TTY guards to their ~/.zshrc to prevent blocking in non-TTY environments:
# Before oh-my-zsh theme/plugin setup:
if [[ -t 0 ]]; then
plugins=(git zsh-syntax-highlighting zsh-autosuggestions)
else
plugins=(git)
fiBut this is a workaround — the app should not require users to modify their shell configuration.