{"record":{"id":"7faae224c276b98b","repo":"wavetermdev/waveterm","slug":"waveterm-tabid-environment-variable-not-set","errorCode":null,"errorMessage":"WAVETERM_TABID environment variable not set","messagePattern":"WAVETERM_TABID environment variable not set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-ai.go","lineNumber":165,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\tmaxSize, sizeStr := getMaxFileSize(mimeType)\n\t\tif len(data) > maxSize {\n\t\t\treturn fmt.Errorf(\"file %s exceeds maximum size of %s for %s files\", fileName, sizeStr, mimeType)\n\t\t}\n\n\t\tallFiles = append(allFiles, wshrpc.AIAttachedFile{\n\t\t\tName:   fileName,\n\t\t\tType:   mimeType,\n\t\t\tSize:   len(data),\n\t\t\tData64: base64.StdEncoding.EncodeToString(data),\n\t\t})\n\t}\n\n\ttabId := os.Getenv(\"WAVETERM_TABID\")\n\tif tabId == \"\" {\n\t\treturn fmt.Errorf(\"WAVETERM_TABID environment variable not set\")\n\t}\n\n\troute := wshutil.MakeTabRouteId(tabId)\n\n\tif aiNewBlockFlag {\n\t\tnewChatData := wshrpc.CommandWaveAIAddContextData{\n\t\t\tNewChat: true,\n\t\t}\n\t\terr := wshclient.WaveAIAddContextCommand(RpcClient, newChatData, &wshrpc.RpcOpts{\n\t\t\tRoute:   route,\n\t\t\tTimeout: rpcTimeout,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"creating new chat: %w\", err)\n\t\t}\n\t}\n\n\tfor _, file := range allFiles {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-ai.go#L147-L183","documentation":"The `wsh ai` command needs to route RPC calls to the Wave terminal block that invoked it. It reads the WAVETERM_TABID environment variable, which Wave sets automatically when running wsh inside a terminal block. If the variable is empty, wsh cannot determine the target tab and returns this error instead of sending an RPC to an unknown route.","triggerScenarios":"Running `wsh ai ...` (with aiRun in cmd/wsh/cmd/wshcmd-ai.go) outside a Wave terminal block, or in any shell where WAVETERM_TABID is unset — e.g. a plain system terminal, SSH session without wsh, CI runner, or a script that cleared the environment (env -i, sudo, docker exec).","commonSituations":"Developers testing `wsh ai` in a regular terminal or IDE shell instead of inside Wave; running the command via sudo/su which strips env vars; invoking from a cron job or CI pipeline where Wave's injected environment is absent.","solutions":["Run the `wsh ai` command from inside a Wave Terminal block, which sets WAVETERM_TABID automatically.","Verify the variable exists with `echo $WAVETERM_TABID`; if empty, reopen the command in a Wave block.","Avoid stripping the environment: don't use `sudo env -i`, `env -i`, or `docker exec` without `-e WAVETERM_TABID`.","If scripting, export WAVETERM_TABID=<tabid> manually to target a known tab."],"exampleFix":"// before (plain terminal)\n$ wsh ai --message \"hello\"  # error: WAVETERM_TABID not set\n\n// after (inside Wave terminal block)\n$ echo $WAVETERM_TABID  # non-empty\n$ wsh ai --message \"hello\"","handlingStrategy":"validation","validationCode":"if os.Getenv(\"WAVETERM_TABID\") == \"\" {\n    // run inside a Wave terminal block before invoking wsh ai\n}","typeGuard":null,"tryCatchPattern":"if err := runAI(); err != nil {\n    if strings.Contains(err.Error(), \"WAVETERM_TABID\") {\n        // fallback: prompt user to run inside Wave Terminal\n    }\n}","preventionTips":["Always execute wsh ai from inside a Wave terminal block.","Check `echo $WAVETERM_TABID` before scripting against wsh ai.","Avoid env-stripping wrappers (sudo env -i, docker exec without -e)."],"tags":["cli","environment-variable","wsh"],"backgroundTag":"missing-env-var","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}