Skip to content

fix: drop -i flag from login shell PATH resolution to prevent SIGTTOU#8836

Closed
michaelneale wants to merge 1 commit into
mainfrom
micn/login-shell-patch
Closed

fix: drop -i flag from login shell PATH resolution to prevent SIGTTOU#8836
michaelneale wants to merge 1 commit into
mainfrom
micn/login-shell-patch

Conversation

@michaelneale

Copy link
Copy Markdown
Collaborator

Category: fix
User Impact: The CLI no longer randomly suspends with "suspended (tty output)" when starting a session.

Problem: Since #8631 ("warm shell PATH lookup during session init"), goose eagerly spawns zsh -l -i -c "echo $PATH" during startup to resolve the user's PATH. The -i (interactive) flag causes zsh to call tcsetpgrp(), stealing the foreground process group from goose. When rustyline then calls tcsetattr to enter raw mode for the input prompt, goose is in a background process group and the kernel sends SIGTTOU, immediately suspending the CLI.

Solution: Drop the -i flag from both call sites. The -l (login) flag alone is sufficient to source .zprofile/.bash_profile where PATH is configured. Interactive mode is unnecessary and actively harmful when the spawned shell shares a controlling terminal with the parent process.

File changes

crates/goose/src/agents/platform_extensions/developer/shell.rs
Removed -i from the shell args in resolve_login_shell_path() for both the flatpak and normal code paths. Added a comment explaining why interactive mode must not be used.

crates/goose-mcp/src/subprocess.rs
Same fix for the equivalent resolve_login_shell_path() used by MCP extension subprocesses.

Reproduction Steps

  1. Build: cargo build --release -p goose-cli
  2. Open a fresh terminal tab
  3. Run ./target/release/goose
  4. Before this fix: the CLI prints the banner then immediately suspends with suspended (tty output)
  5. After this fix: the CLI prints the banner and shows the input prompt normally

The resolve_login_shell_path() function spawns a shell with -l -i -c to
recover the user's PATH. The -i (interactive) flag causes zsh to call
tcsetpgrp(), stealing the foreground process group from the parent goose
process. When rustyline later calls tcsetattr to enter raw mode, goose
is in a background process group and receives SIGTTOU, suspending the
CLI immediately after the banner prints.

Since commit b7aea3d ('warm shell PATH lookup during session init'),
this shell is spawned eagerly at startup rather than lazily on first
shell command, making the race condition much more likely to trigger.

The -l (login) flag alone is sufficient to source .zprofile/.bash_profile
where PATH modifications are typically configured.

Signed-off-by: Michael Neale <[email protected]>
@michaelneale
michaelneale requested review from DOsinga and jamadeo April 24, 2026 23:04
@michaelneale
michaelneale marked this pull request as ready for review April 24, 2026 23:05
@michaelneale

Copy link
Copy Markdown
Collaborator Author

@jamadeo I am not sure if this is just my pathological env, but was consistently an issue for me just today until -i was removed (as would time out and leave goose orphaned somehow each time) - might not be right solution though.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bcc2955009

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// `-l` (login) is sufficient to source profile files where PATH is set.
std::process::Command::new(&shell)
.args(["-l", "-i", "-c", "echo $PATH"])
.args(["-l", "-c", "echo $PATH"])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore interactive PATH fallback for shell probing

Switching the probe to -l -c only means shells that split startup files by mode (notably zsh) no longer load interactive rc files like .zshrc, where many users keep PATH additions for tools such as nvm/pyenv/asdf; in GUI/desktop launches with a minimal inherited PATH, this can make MCP subprocesses fail to find expected binaries after this commit. Please keep the SIGTTOU fix but add a safe fallback path-resolution strategy that preserves interactive PATH entries when login-only output is incomplete.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yeah this is true - so I am confused as to what we should do.

@leoschwarz

leoschwarz commented Apr 25, 2026

Copy link
Copy Markdown

My first experience with Goose was it just crashes on start up and even takes down my shell (Konsole on KDE), so I came across your PR.

Edit: goose session --no-profile works

I think it might possibly be due to fish shell being my login shell and the echo $PATH which is used by goose printing spaces rather than colon like in bash.

Bojun-Vvibe added a commit to Bojun-Vvibe/oss-contributions that referenced this pull request Apr 26, 2026
- QwenLM/qwen-code#3642: BackgroundShellRegistry + /bashes (merge-after-nits)
- cline/cline#10384: maxRetryAfter cap with test-cleanup hazard (request-changes)
- aaif-goose/goose#8836: drop -i flag SIGTTOU fix (merge-as-is)
@jamadeo

jamadeo commented Apr 27, 2026

Copy link
Copy Markdown
Member

merged #8804 which should fix this

@jamadeo jamadeo closed this Apr 27, 2026
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.

3 participants