{"record":{"id":"c905e973899e414d","repo":"wavetermdev/waveterm","slug":"error-checking-wsh-version-w-c905e9","errorCode":null,"errorMessage":"error checking wsh version: %w","messagePattern":"error checking wsh version: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wslconn/wslconn.go","lineNumber":298,"sourceCode":"\tcmd.SetStderr(pipeWrite)\n\tcmd.SetStdin(inputPipeRead)\n\tlog.Printf(\"starting conn controller: %q\\n\", cmdStr)\n\tblocklogger.Debugf(ctx, \"[conndebug] wrapped command:\\n%s\\n\", shWrappedCmdStr)\n\terr := cmd.Start()\n\tif err != nil {\n\t\treturn false, \"\", \"\", fmt.Errorf(\"unable to start conn controller cmd: %w\", err)\n\t}\n\tlinesChan := utilfn.StreamToLinesChan(pipeRead)\n\tversionLine, err := utilfn.ReadLineWithTimeout(linesChan, 30*time.Second)\n\tif err != nil {\n\t\tcancelFn()\n\t\treturn false, \"\", \"\", fmt.Errorf(\"error reading wsh version: %w\", err)\n\t}\n\tconn.Infof(ctx, \"got connserver version: %s\\n\", strings.TrimSpace(versionLine))\n\tisUpToDate, clientVersion, osArchStr, err := conncontroller.IsWshVersionUpToDate(ctx, versionLine)\n\tif err != nil {\n\t\tcancelFn()\n\t\treturn false, \"\", \"\", fmt.Errorf(\"error checking wsh version: %w\", err)\n\t}\n\tif isUpToDate && !afterUpdate && os.Getenv(wavebase.WaveWshForceUpdateVarName) != \"\" {\n\t\tisUpToDate = false\n\t\tconn.Infof(ctx, \"%s set, forcing wsh update\\n\", wavebase.WaveWshForceUpdateVarName)\n\t}\n\tconn.Infof(ctx, \"connserver up-to-date: %v\\n\", isUpToDate)\n\tif !isUpToDate {\n\t\tcancelFn()\n\t\treturn true, clientVersion, osArchStr, nil\n\t}\n\tconn.WithLock(func() {\n\t\tconn.ConnController = cmd\n\t})\n\t// service the I/O\n\tgo func() {\n\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(\"wslconn:cmd.Wait\", recover())\n\t\t}()","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wslconn/wslconn.go#L280-L316","documentation":"StartConnServer launched the wsh connserver inside the WSL distro and read its first stdout line (the version string). That version line was then passed to conncontroller.IsWshVersionUpToDate, which failed to parse it or to compare it against the local wsh version. The error wraps the underlying cause, so the real problem is usually a malformed or empty version line rather than a connection failure.","triggerScenarios":"Calling WslConn.StartConnServer (via tryEnableWsh) when the remote wsh binary emits an unparseable first stdout line: a corrupted/hand-edited wsh binary, a shell profile printing banner text before the version, a non-English locale altering output, or a version string from a much older/newer wsh that the parser rejects.","commonSituations":"Users with shell rc files that echo text on non-interactive shells; stale wsh binaries from an interrupted earlier update; custom wsh builds whose version doesn't match the expected semver format; WSL distros where PATH resolves a different wsh than the one Wave installed.","solutions":["Reinstall/update wsh in the distro so the version line is current and well-formed (WslConn.InstallWsh or UpdateWsh, or run the update from the Wave UI)","Check the distro's shell profiles (.bashrc/.profile) for output on non-interactive shells and silence it","Verify the wsh binary is the official one: run 'wsh version' manually inside the distro and check the output format","Read the wrapped error (%w) for the concrete parse failure and match it against your wsh version"],"exampleFix":"// before: connserver emits banner text before version\n// .bashrc: echo \"Welcome to my distro\"\n// after\n// .bashrc: [[ $- == *i* ]] && echo \"Welcome to my distro\"  # only for interactive shells","handlingStrategy":"try-catch","validationCode":"// verify wsh in the distro emits a clean version line before starting the connserver\nout, err := exec.Command(\"wsl\", \"-d\", distroName, \"--\", wshPath, \"version\").Output()\nif err != nil || !regexp.MustCompile(`^\\d+\\.\\d+\\.\\d+`).Match(bytes.TrimSpace(out)) {\n    // wsh missing or output polluted — reinstall before StartConnServer\n}","typeGuard":null,"tryCatchPattern":"if _, _, _, err := conn.StartConnServer(ctx, false); err != nil {\n    if strings.Contains(err.Error(), \"error checking wsh version\") {\n        // reinstall wsh, silence shell banners, then retry\n        _ = conn.InstallWsh(ctx, \"\")\n        _, _, _, err = conn.StartConnServer(ctx, false)\n    }\n}","preventionTips":["Keep shell rc files silent for non-interactive shells (guard echoes with [[ $- == *i* ]])","Keep wsh updated so its version string always parses","Never hand-replace the wsh binary with a custom build"],"tags":["wsl","wsh","version-parsing","connserver"],"backgroundTag":"wsh-version-parse-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}