wavetermdev/waveterm · error
invalid term size: %v
Error message
invalid term size: %v
What it means
StartWslShellProcNoWsh validates the terminal size before starting the pty. After defaulting zero-valued Rows/Cols to shellutil.DefaultTermRows/DefaultTermCols, it rejects sizes that are still <= 0 with "invalid term size: %v". This prevents passing nonsensical Winsize values to pty.StartWithSize.
Source
Thrown at pkg/shellexec/shellexec.go:166
return err2
}
func (pp *PipePty) WriteString(s string) (n int, err error) {
return pp.Write([]byte(s))
}
func StartWslShellProcNoWsh(ctx context.Context, termSize waveobj.TermSize, cmdStr string, cmdOpts CommandOptsType, conn *wslconn.WslConn) (*ShellProc, error) {
client := conn.GetClient()
conn.Infof(ctx, "WSL-NEWSESSION (StartWslShellProcNoWsh)")
ecmd := exec.Command("wsl.exe", "~", "-d", client.Name())
if termSize.Rows == 0 || termSize.Cols == 0 {
termSize.Rows = shellutil.DefaultTermRows
termSize.Cols = shellutil.DefaultTermCols
}
if termSize.Rows <= 0 || termSize.Cols <= 0 {
return nil, fmt.Errorf("invalid term size: %v", termSize)
}
cmdPty, err := pty.StartWithSize(ecmd, &pty.Winsize{Rows: uint16(termSize.Rows), Cols: uint16(termSize.Cols)})
if err != nil {
return nil, err
}
cmdWrap := MakeCmdWrap(ecmd, cmdPty, true)
return &ShellProc{Cmd: cmdWrap, ConnName: conn.GetName(), CloseOnce: &sync.Once{}, DoneCh: make(chan any)}, nil
}
func StartWslShellProc(ctx context.Context, termSize waveobj.TermSize, cmdStr string, cmdOpts CommandOptsType, conn *wslconn.WslConn) (*ShellProc, error) {
if cmdOpts.SwapToken == nil {
return nil, fmt.Errorf("SwapToken is required in CommandOptsType")
}
client := conn.GetClient()
conn.Infof(ctx, "WSL-NEWSESSION (StartWslShellProc)")
connRoute := wshutil.MakeConnectionRouteId(conn.GetName())
rpcClient := wshclient.GetBareRpcClient()
remoteInfo, err := wshclient.RemoteGetInfoCommand(rpcClient, &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000})View on GitHub (pinned to a4447c1563)
Solutions
- Ensure Rows/Cols are positive before calling, or pass 0 to use defaults
- Sanitize the TermSize: clamp negative values to defaults instead of passing them through
- Fix the resize event/state source producing negative dimensions
Example fix
// before
ts := waveobj.TermSize{Rows: -1, Cols: 30}
proc, err := shellexec.StartWslShellProcNoWsh(ctx, ts, cmdStr, cmdOpts, conn)
// after
if ts.Rows <= 0 { ts.Rows = shellutil.DefaultTermRows }
if ts.Cols <= 0 { ts.Cols = shellutil.DefaultTermCols }
proc, err := shellexec.StartWslShellProcNoWsh(ctx, ts, cmdStr, cmdOpts, conn) Defensive patterns
Strategy: validation
Validate before calling
if termSize.Rows < 0 { termSize.Rows = shellutil.DefaultTermRows }
if termSize.Cols < 0 { termSize.Cols = shellutil.DefaultTermCols } Type guard
func validTermSize(ts waveobj.TermSize) bool {
return ts.Rows >= 0 && ts.Cols >= 0 // 0 means use defaults
} Try / catch
proc, err := shellexec.StartWslShellProcNoWsh(ctx, termSize, cmdStr, cmdOpts, conn)
if err != nil && strings.Contains(err.Error(), "invalid term size") {
termSize = waveobj.TermSize{Rows: shellutil.DefaultTermRows, Cols: shellutil.DefaultTermCols}
proc, err = shellexec.StartWslShellProcNoWsh(ctx, termSize, cmdStr, cmdOpts, conn)
} Prevention
- Clamp term sizes to positive values on every resize event
- Validate persisted TermSize when loading block state
- Never construct TermSize manually without bounds checks
When it happens
Trigger: Calling StartWslShellProcNoWsh with a waveobj.TermSize whose Rows or Cols is negative (0 is auto-corrected to defaults, negatives are not), e.g. a termSize built from garbage/corrupt block state.
Common situations: Term size persisted as negative values after a malformed resize event; caller constructing TermSize manually with invalid dimensions.
Related errors
- SwapToken is required in CommandOptsType
- invalid AIMessage: %w
- part %d: text type requires non-empty text field
- failed to build shell command: %w
- invalid term size: %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/40bb01ac81feb1b7.
Report an issue: GitHub.