Skip to content

gh cs ssh can hide errors on port forwarding #11206

Description

@williammartin

Describe the bug

When running gh cs ssh we forward the codespaces internal port (16634) in order to connect via GRPC.

// Tunnel the remote gRPC server port to the local port
go func() {
// Start forwarding the port locally
opts := portforwarder.ForwardPortOpts{
Port: codespacesInternalPort,
Internal: true,
}
ch <- fwd.ForwardPortToListener(pfctx, opts, listener)
}()
var conn *grpc.ClientConn
go func() {
// Attempt to connect to the port
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
}
conn, err = grpc.NewClient(localAddress, opts...)
ch <- err // nil if we successfully connected
}()
// Wait for the connection to be established or for the context to be cancelled
select {
case <-ctx.Done():
return nil, ctx.Err()
case err := <-ch:
if err != nil {
return nil, err
}
}

Both the port forward and the grpc client construction write to ch when completing, then the select unblocks. However, we've seen port forwarding fail but grpc client construction succeed, resulting in a failure much down the line that was not surfaced.

Affected version

➜  gh version
gh version 2.74.2 (2025-06-17)
https://github.com/cli/cli/releases/tag/v2.74.2

Steps to reproduce the behavior

Not possible to produce without a port forwarding issue or code changes.

Apply the following patch and see that the error doesn't bubble up:

diff --git a/internal/codespaces/rpc/invoker.go b/internal/codespaces/rpc/invoker.go
index 6ba8843ac..d1d19e5b9 100644
--- a/internal/codespaces/rpc/invoker.go
+++ b/internal/codespaces/rpc/invoker.go
@@ -5,6 +5,7 @@ package rpc
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net"
 	"os"
@@ -104,12 +105,8 @@ func connect(ctx context.Context, fwd portforwarder.PortForwarder) (Invoker, err
 
 	// Tunnel the remote gRPC server port to the local port
 	go func() {
-		// Start forwarding the port locally
-		opts := portforwarder.ForwardPortOpts{
-			Port:     codespacesInternalPort,
-			Internal: true,
-		}
-		ch <- fwd.ForwardPortToListener(pfctx, opts, listener)
+		time.Sleep(time.Second)
+		ch <- errors.New("omg")
 	}()
 
 	var conn *grpc.ClientConn

Activity

  1. added
    bugSomething isn't working
    priority-3Affects a small number of users or is largely cosmetic
    gh-codespacerelating to the gh codespace command
    on Jul 2, 2025
  2. Mishra-coder commented on Mar 23, 2026

    @Mishra-coder

    Hi! I’d like to work on this issue. Could you please assign it to me? I’ll make sure to follow the contribution guidelines. Thanks!

  3. added a commit that references this issue on Apr 10, 2026
    c2f20eb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcodespacesgh-codespacerelating to the gh codespace commandpriority-3Affects a small number of users or is largely cosmetic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions