wavetermdev/waveterm · error

invalid format of user@host argument

Error message

invalid format of user@host argument

What it means

ParseOpts parses an SSH 'user@host' (optionally 'host' or 'user@host:port') string into SSHOpts using the userHostRe regular expression. This error is returned when the input string does not match the pattern, i.e. it is not a syntactically valid user@host argument. It is a pure input-validation error thrown before any network activity.

Source

Thrown at pkg/remote/connutil.go:34

	"strings"
	"text/template"
	"time"

	"github.com/wavetermdev/waveterm/pkg/blocklogger"
	"github.com/wavetermdev/waveterm/pkg/genconn"
	"github.com/wavetermdev/waveterm/pkg/util/iterfn"
	"github.com/wavetermdev/waveterm/pkg/util/shellutil"
	"github.com/wavetermdev/waveterm/pkg/wavebase"
	"github.com/wavetermdev/waveterm/pkg/wconfig"
	"golang.org/x/crypto/ssh"
)

var userHostRe = regexp.MustCompile(`^([a-zA-Z0-9][a-zA-Z0-9._@\\-]*@)?([a-zA-Z0-9][a-zA-Z0-9.-]*)(?::([0-9]+))?$`)

func ParseOpts(input string) (*SSHOpts, error) {
	m := userHostRe.FindStringSubmatch(input)
	if m == nil {
		return nil, fmt.Errorf("invalid format of user@host argument")
	}
	remoteUser, remoteHost, remotePort := m[1], m[2], m[3]
	remoteUser = strings.Trim(remoteUser, "@")

	return &SSHOpts{SSHHost: remoteHost, SSHUser: remoteUser, SSHPort: remotePort}, nil
}

func normalizeOs(os string) string {
	os = strings.ToLower(strings.TrimSpace(os))
	return os
}

func normalizeArch(arch string) string {
	arch = strings.ToLower(strings.TrimSpace(arch))
	switch arch {
	case "x86_64", "amd64":
		arch = "x64"
	case "arm64", "aarch64":

View on GitHub (pinned to a4447c1563)

Solutions

  1. Trim whitespace and remove any 'ssh://' or 'ssh ' prefix from the input before calling ParseOpts.
  2. Use a plain hostname or user@host[:port] form; for IPv6, use resolvable DNS names or preprocess the address outside this parser.
  3. Validate the string against a copy of userHostRe in the caller before invoking, to give a better error message.
  4. If a username contains characters outside [a-zA-Z0-9._@\-], restructure the input or extend the regex in connutil.go.

Example fix

// before
opts, err := connutil.ParseOpts("ssh user@host") // invalid: 'ssh ' prefix
// after
input := strings.TrimSpace(strings.TrimPrefix(strings.TrimPrefix(input, "ssh://"), "ssh "))
opts, err := connutil.ParseOpts(input)
Defensive patterns

Strategy: validation

Validate before calling

var userHostRe = regexp.MustCompile(`^([a-zA-Z0-9][a-zA-Z0-9._@\\-]*@)?([a-zA-Z0-9][a-zA-Z0-9.-]*)(?::([0-9]+))?$`)
func validUserHost(s string) bool { return userHostRe.MatchString(strings.TrimSpace(s)) }
// call connutil.ParseOpts only if validUserHost(input)

Try / catch

opts, err := connutil.ParseOpts(input)
if err != nil {
    return fmt.Errorf("connection target %q is not valid user@host[:port]; got: %w", input, err)
}

Prevention

When it happens

Trigger: Calling ParseOpts with a string failing userHostRe: empty string, leading/trailing whitespace, IPv6 address ([::1] or ::1), hostname with protocol prefix (ssh://host), username starting with non-alphanumeric, port with non-digits, or multiple '@' placed incorrectly.

Common situations: Users pasting 'ssh user@host' with the 'ssh ' prefix into connection settings; IPv6 targets; hostnames with underscores or unicode characters; trailing slashes or spaces copied from terminal output; invalid entries stored in saved connection configs validated by validateConnectionName or applySSHOverrides.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/5bea8683b0fb3fbb. Report an issue: GitHub.