{"record":{"id":"40bb01ac81feb1b7","repo":"wavetermdev/waveterm","slug":"invalid-term-size-v-40bb01","errorCode":null,"errorMessage":"invalid term size: %v","messagePattern":"invalid term size: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/shellexec/shellexec.go","lineNumber":166,"sourceCode":"\treturn err2\n}\n\nfunc (pp *PipePty) WriteString(s string) (n int, err error) {\n\treturn pp.Write([]byte(s))\n}\n\nfunc StartWslShellProcNoWsh(ctx context.Context, termSize waveobj.TermSize, cmdStr string, cmdOpts CommandOptsType, conn *wslconn.WslConn) (*ShellProc, error) {\n\tclient := conn.GetClient()\n\tconn.Infof(ctx, \"WSL-NEWSESSION (StartWslShellProcNoWsh)\")\n\n\tecmd := exec.Command(\"wsl.exe\", \"~\", \"-d\", client.Name())\n\n\tif termSize.Rows == 0 || termSize.Cols == 0 {\n\t\ttermSize.Rows = shellutil.DefaultTermRows\n\t\ttermSize.Cols = shellutil.DefaultTermCols\n\t}\n\tif termSize.Rows <= 0 || termSize.Cols <= 0 {\n\t\treturn nil, fmt.Errorf(\"invalid term size: %v\", termSize)\n\t}\n\tcmdPty, err := pty.StartWithSize(ecmd, &pty.Winsize{Rows: uint16(termSize.Rows), Cols: uint16(termSize.Cols)})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcmdWrap := MakeCmdWrap(ecmd, cmdPty, true)\n\treturn &ShellProc{Cmd: cmdWrap, ConnName: conn.GetName(), CloseOnce: &sync.Once{}, DoneCh: make(chan any)}, nil\n}\n\nfunc StartWslShellProc(ctx context.Context, termSize waveobj.TermSize, cmdStr string, cmdOpts CommandOptsType, conn *wslconn.WslConn) (*ShellProc, error) {\n\tif cmdOpts.SwapToken == nil {\n\t\treturn nil, fmt.Errorf(\"SwapToken is required in CommandOptsType\")\n\t}\n\tclient := conn.GetClient()\n\tconn.Infof(ctx, \"WSL-NEWSESSION (StartWslShellProc)\")\n\tconnRoute := wshutil.MakeConnectionRouteId(conn.GetName())\n\trpcClient := wshclient.GetBareRpcClient()\n\tremoteInfo, err := wshclient.RemoteGetInfoCommand(rpcClient, &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000})","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/shellexec/shellexec.go#L148-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"Term size persisted as negative values after a malformed resize event; caller constructing TermSize manually with invalid dimensions.","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"],"exampleFix":"// before\nts := waveobj.TermSize{Rows: -1, Cols: 30}\nproc, err := shellexec.StartWslShellProcNoWsh(ctx, ts, cmdStr, cmdOpts, conn)\n// after\nif ts.Rows <= 0 { ts.Rows = shellutil.DefaultTermRows }\nif ts.Cols <= 0 { ts.Cols = shellutil.DefaultTermCols }\nproc, err := shellexec.StartWslShellProcNoWsh(ctx, ts, cmdStr, cmdOpts, conn)","handlingStrategy":"validation","validationCode":"if termSize.Rows < 0 { termSize.Rows = shellutil.DefaultTermRows }\nif termSize.Cols < 0 { termSize.Cols = shellutil.DefaultTermCols }","typeGuard":"func validTermSize(ts waveobj.TermSize) bool {\n    return ts.Rows >= 0 && ts.Cols >= 0 // 0 means use defaults\n}","tryCatchPattern":"proc, err := shellexec.StartWslShellProcNoWsh(ctx, termSize, cmdStr, cmdOpts, conn)\nif err != nil && strings.Contains(err.Error(), \"invalid term size\") {\n    termSize = waveobj.TermSize{Rows: shellutil.DefaultTermRows, Cols: shellutil.DefaultTermCols}\n    proc, err = shellexec.StartWslShellProcNoWsh(ctx, termSize, cmdStr, cmdOpts, conn)\n}","preventionTips":["Clamp term sizes to positive values on every resize event","Validate persisted TermSize when loading block state","Never construct TermSize manually without bounds checks"],"tags":["go","wsl","pty","term-size","validation"],"backgroundTag":"invalid-term-size","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}