{"record":{"id":"0f7c8d2d10c97752","repo":"wavetermdev/waveterm","slug":"failed-to-prepare-install-command-w","errorCode":null,"errorMessage":"failed to prepare install command: %w","messagePattern":"failed to prepare install command: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/connutil.go","lineNumber":121,"sourceCode":"\t\tblocklogger.Debugf(ctx, \"[conndebug] CpWshToRemote, timeout: %v\\n\", time.Until(deadline))\n\t}\n\twshLocalPath, err := shellutil.GetLocalWshBinaryPath(wavebase.WaveVersion, clientOs, clientArch)\n\tif err != nil {\n\t\treturn err\n\t}\n\tinput, err := os.Open(wshLocalPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot open local file %s: %w\", wshLocalPath, err)\n\t}\n\tdefer input.Close()\n\tinstallWords := map[string]string{\n\t\t\"installDir\":  filepath.ToSlash(filepath.Dir(wavebase.RemoteFullWshBinPath)),\n\t\t\"tempPath\":    wavebase.RemoteFullWshBinPath + \".temp\",\n\t\t\"installPath\": wavebase.RemoteFullWshBinPath,\n\t}\n\tvar installCmd bytes.Buffer\n\tif err := installTemplate.Execute(&installCmd, installWords); err != nil {\n\t\treturn fmt.Errorf(\"failed to prepare install command: %w\", err)\n\t}\n\tblocklogger.Infof(ctx, \"[conndebug] copying %q to remote server %q\\n\", wshLocalPath, wavebase.RemoteFullWshBinPath)\n\tgenCmd, err := genconn.MakeSSHCmdClient(client, genconn.CommandSpec{\n\t\tCmd: installCmd.String(),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create remote command: %w\", err)\n\t}\n\tstdin, err := genCmd.StdinPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get stdin pipe: %w\", err)\n\t}\n\tdefer stdin.Close()\n\tstderrBuf, err := genconn.MakeStderrSyncBuffer(genCmd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get stderr pipe: %w\", err)\n\t}\n\tif err := genCmd.Start(); err != nil {","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/connutil.go#L103-L139","documentation":"CpWshToRemote renders a Go text/template (installTemplate) that builds the remote shell command which installs the uploaded wsh binary. This error is wrapped when template execution against the installWords map fails. Since the template inputs are simple strings, this almost always indicates a template definition/parsing problem rather than bad runtime data.","triggerScenarios":"installTemplate.Execute returns an error — typically the template was parsed from a malformed/changed definition (syntax error, invalid pipeline referencing a missing function), or Execute is invoked on a template that failed to parse at init.","commonSituations":"Modifying installTemplate in connutil.go and introducing a syntax error or an unknown template function; running a build where the package-level template parse failed silently until first Execute.","solutions":["Inspect installTemplate's text in connutil.go for template syntax errors (unclosed {{ }}, unknown functions) and fix them.","Check that the template is parsed with Must(text/template.New(...).Parse(...)) at package init so parse errors surface at startup.","If recently rebased/upgraded, diff installTemplate against the upstream version to find the corruption.","As a workaround, replace templating with fmt.Sprintf substitution for the three fixed keys (installDir, tempPath, installPath)."],"exampleFix":"// before\nvar installTemplate = template.Must(template.New(\"install\").Parse(\n    \"cat {{.tempPath}} | {{.badFunc {{.installDir}}\"))\n// after\nvar installTemplate = template.Must(template.New(\"install\").Parse(\n    \"mkdir -p {{.installDir}} && cat > {{.tempPath}} && mv {{.tempPath}} {{.installPath}}\"))","handlingStrategy":"try-catch","validationCode":"// render the template early to catch errors before opening files/connections\nvar probe bytes.Buffer\nif err := installTemplate.Execute(&probe, map[string]string{\"installDir\": \"x\", \"tempPath\": \"y\", \"installPath\": \"z\"}); err != nil {\n    return fmt.Errorf(\"install template broken: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := connutil.CpWshToRemote(ctx, client, os, arch)\nif err != nil && strings.Contains(err.Error(), \"failed to prepare install command\") {\n    return fmt.Errorf(\"internal template error; report/repair installTemplate: %w\", err)\n}","preventionTips":["Use template.Must at package init so parse errors fail fast at startup.","Keep installTemplate a fixed, reviewed literal; avoid generating it dynamically.","Add a unit test that executes installTemplate with dummy data.","Prefer fmt.Sprintf for simple key substitutions with no control flow."],"tags":["go","template","wsh","installation"],"backgroundTag":"template-execution-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}