fix(cli): enhance error handling for multiple agents in SSH command (#19943)

Closes #19812

## Problem
> When I try to SSH into my workspace with multiple agents. It does not
provide an intuitive way to do that successfully and instead misguides
by printing wrong instructions.

This PR enhances the error handling to provide suggestions with SSH
commands that users can copy and paste directly.

Before:
```
Encountered an error running "coder ssh", see "coder ssh --help" for more information
error: multiple agents found, please specify the agent name, available agents: [coder dev]
```

After:
```
Encountered an error running "coder ssh", see "coder ssh --help" for more information
error: multiple agents found, please specify the agent name, available agents: [coder dev]
Try running:
         $ ssh coder.dogfood.me.coder
         $ ssh dev.dogfood.me.coder
```
This commit is contained in:
Kacper Sawicki
2025-09-25 12:03:51 +02:00
committed by GitHub
parent da467bad2a
commit c8742badbb
+19 -3
View File
@@ -756,7 +756,23 @@ func findWorkspaceAndAgentByHostname(
hostname = strings.TrimSuffix(hostname, qualifiedSuffix)
}
hostname = normalizeWorkspaceInput(hostname)
ws, agent, _, err := GetWorkspaceAndAgent(ctx, inv, client, !disableAutostart, hostname)
ws, agent, otherAgents, err := GetWorkspaceAndAgent(ctx, inv, client, !disableAutostart, hostname)
if err != nil && strings.Contains(err.Error(), "multiple agents found") {
var errorMsg strings.Builder
_, _ = errorMsg.WriteString(fmt.Sprintf("%s\nTry running:\n", err.Error()))
for _, agent := range otherAgents {
switch {
case config.HostnameSuffix != "":
_, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s.%s.%s.%s", agent.Name, ws.Name, ws.OwnerName, config.HostnameSuffix))))
case config.HostnamePrefix != "":
_, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s%s.%s.%s", config.HostnamePrefix, agent.Name, ws.Name, ws.OwnerName))))
default:
_, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s.%s.%s", agent.Name, ws.Name, ws.OwnerName))))
}
}
return ws, agent, xerrors.New(errorMsg.String())
}
return ws, agent, err
}
@@ -922,7 +938,7 @@ func GetWorkspaceAndAgent(ctx context.Context, inv *serpent.Invocation, client *
}
workspaceAgent, otherWorkspaceAgents, err := getWorkspaceAgent(workspace, agentName)
if err != nil {
return codersdk.Workspace{}, codersdk.WorkspaceAgent{}, nil, err
return workspace, codersdk.WorkspaceAgent{}, otherWorkspaceAgents, err
}
return workspace, workspaceAgent, otherWorkspaceAgents, nil
@@ -958,7 +974,7 @@ func getWorkspaceAgent(workspace codersdk.Workspace, agentName string) (workspac
if len(agents) == 1 {
return agents[0], nil, nil
}
return codersdk.WorkspaceAgent{}, nil, xerrors.Errorf("multiple agents found, please specify the agent name, available agents: %v", availableNames)
return codersdk.WorkspaceAgent{}, agents, xerrors.Errorf("multiple agents found, please specify the agent name, available agents: %v", availableNames)
}
// Attempt to poll workspace autostop. We write a per-workspace lockfile to