wavetermdev/waveterm · error

error getting environment without PTY: %w

Error message

error getting environment without PTY: %w

What it means

After obtaining the ssh client, GetEnvironmentMaps runs a first probe that executes a command WITHOUT allocating a PTY to capture the environment. Any failure in that session (command error, channel failure, dropped connection) is wrapped as 'error getting environment without PTY'.

Source

Thrown at pkg/remote/conncontroller/conncontroller.go:341

	}
	clientVersion := parts[1]
	expectedVersion := fmt.Sprintf("v%s", wavebase.WaveVersion)
	if semver.Compare(clientVersion, expectedVersion) < 0 {
		return false, clientVersion, "", nil
	}
	return true, clientVersion, "", nil
}

// for testing only -- trying to determine the env difference when attaching or not attaching a pty to an ssh session
func (conn *SSHConn) GetEnvironmentMaps(ctx context.Context) (map[string]string, map[string]string, error) {
	client := conn.GetClient()
	if client == nil {
		return nil, nil, fmt.Errorf("ssh client is not connected")
	}

	noPtyEnv, err := conn.getEnvironmentNoPty(ctx, client)
	if err != nil {
		return nil, nil, fmt.Errorf("error getting environment without PTY: %w", err)
	}

	ptyEnv, err := conn.getEnvironmentWithPty(ctx, client)
	if err != nil {
		return nil, nil, fmt.Errorf("error getting environment with PTY: %w", err)
	}

	return noPtyEnv, ptyEnv, nil
}

func runSessionWithContext(ctx context.Context, session *ssh.Session, cmd string) error {
	errCh := make(chan error, 1)

	go func() {
		errCh <- session.Run(cmd)
	}()

	select {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped inner error for the actual SSH/shell failure
  2. Test manual non-interactive SSH command execution (ssh host 'env') to reproduce
  3. Fix remote shell startup files that error or emit unexpected output in non-interactive mode
  4. Check sshd MaxSessions and connection stability

Example fix

// before
noPtyEnv, err := conn.getEnvironmentNoPty(ctx, client)
// remote .bashrc prints to stdout, corrupting/failing the env probe
// after: guard profile output
[[ $- == *i* ]] || return   // in ~/.bashrc: skip setup for non-interactive shells
Defensive patterns

Strategy: try-catch

Validate before calling

// non-interactive probe precheck
out, err := client.CombinedOutput("true")
if err != nil {
    return fmt.Errorf("remote cannot run commands: %v", err)
}

Try / catch

noPty, pty, err := conn.GetEnvironmentMaps(ctx)
if err != nil && strings.Contains(err.Error(), "environment without PTY") {
    log.Printf("env probe (no pty) failed: %v", err) // inspect wrapped cause
}

Prevention

When it happens

Trigger: conn.getEnvironmentNoPty returns an error — the remote shell command fails, the SSH channel cannot be opened, or the connection drops during the probe.

Common situations: Remote shell startup errors (broken .bashrc/.profile emitting output or failing); sshd MaxSessions exhausted; connection reset mid-command; restricted shell that forbids command execution.

Related errors


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