Skip to content

fix(tunnel): do not log an error when the container tunnel is closed - #2

Merged
renatoathaydes merged 1 commit into
mainfrom
fix/ssh-tunnel-closed-error
Oct 11, 2026
Merged

renatoathaydes merged 1 commit into
mainfrom
fix/ssh-tunnel-closed-error

Conversation

@renatoathaydes

Copy link
Copy Markdown
Collaborator

Problem

After devpod ssh commands that worked, this error can be printed:

Error tunneling to container: wait: remote command exited without exit status or exit signal

When devpod ssh finishes, runInContainer cancels the container tunnel. That closes the tunnel's SSH session before the remote command can send an exit status, so ssh.Run returns an error. The tunnel goroutine logged every error, this expected one included.

Change

fix(tunnel): if the tunnel's context was already cancelled, the error is logged at debug level ("Container tunnel closed"); any other tunnel error is still logged as an error.

Ported from skevetter/devpod 371e52e (#586). That version checked errors.Is(err, context.Canceled), which relied on skevetter's ssh.Run returning the context error. Here ssh.Run returns the raw session error, so the context is checked directly. The context is always cancelled before the session is closed this way, so the check doesn't depend on timing.

Testing

  • On kubernetes, loft-sh's v0.6.15 release printed the error after every devpod ssh --command 'echo hi' (3 of 3).
  • With a build of main and a matching agent, neither the unfixed nor the fixed build printed it (8 of 8 each). Debug logs show devpod ssh exits before the tunnel goroutine logs, so with main the error is currently hidden by timing only.
  • go vet and golangci-lint v1.60.1 (the version CI uses): no issues. No unit test was added; pkg/tunnel has none, and this would need a fake SSH server for a one-condition change.

🤖 Generated with Claude Code

When `devpod ssh` finishes, runInContainer cancels the container tunnel,
which closes its SSH session before the remote command can send an exit
status. The tunnel goroutine logged that as
"Error tunneling to container: wait: remote command exited without exit
status or exit signal" even though everything worked. Whether it was
printed depended on the goroutine logging before the process exited.

It is now logged at debug level when the tunnel's context was cancelled,
and as an error otherwise. Ported from skevetter/devpod 371e52e (#586),
adapted because ssh.Run here returns the session error rather than the
context error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renatoathaydes
renatoathaydes merged commit 903dedc into main Oct 11, 2026
4 of 22 checks passed
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