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
- Inspect the wrapped inner error for the actual SSH/shell failure
- Test manual non-interactive SSH command execution (ssh host 'env') to reproduce
- Fix remote shell startup files that error or emit unexpected output in non-interactive mode
- 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
- Keep remote non-interactive shell startup clean (no stdout noise, no failures)
- Check sshd MaxSessions and connection limits
- Verify basic command execution (ssh host true) works before diagnostics
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
- error getting environment with PTY: %w
- setting auth key: %v
- cannot parse connection name: %w
- getting ssh connection status: %w
- connecting connection: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/b1658b04335ba467.
Report an issue: GitHub.