wavetermdev/waveterm · error

no WAVETERM_TABID env var set

Error message

no WAVETERM_TABID env var set

What it means

`wsh editor` needs to know which Wave terminal tab to open the editor block in. It reads this from the WAVETERM_TABID environment variable (via getTabIdFromEnv). When the variable is empty or unset, editorRun refuses to proceed because it cannot target a block parent.

Source

Thrown at cmd/wsh/cmd/wshcmd-editor.go:60

		OutputHelpMessage(cmd)
		return fmt.Errorf("too many arguments.  wsh editor requires exactly one argument")
	}
	fileArg := args[0]
	absFile, err := filepath.Abs(fileArg)
	if err != nil {
		return fmt.Errorf("getting absolute path: %w", err)
	}
	_, err = os.Stat(absFile)
	if err == fs.ErrNotExist {
		return fmt.Errorf("file does not exist: %q", absFile)
	}
	if err != nil {
		return fmt.Errorf("getting file info: %w", err)
	}

	tabId := getTabIdFromEnv()
	if tabId == "" {
		return fmt.Errorf("no WAVETERM_TABID env var set")
	}

	wshCmd := wshrpc.CommandCreateBlockData{
		TabId: tabId,
		BlockDef: &waveobj.BlockDef{
			Meta: map[string]any{
				waveobj.MetaKey_View: "preview",
				waveobj.MetaKey_File: absFile,
				waveobj.MetaKey_Edit: true,
			},
		},
		Magnified: editMagnified,
		Focused:   true,
	}
	if RpcContext.Conn != "" {
		wshCmd.BlockDef.Meta[waveobj.MetaKey_Connection] = RpcContext.Conn
	}
	blockRef, err := wshclient.CreateBlockCommand(RpcClient, wshCmd, &wshrpc.RpcOpts{Timeout: 2000})

View on GitHub (pinned to a4447c1563)

Solutions

  1. Run the `wsh editor` command from a terminal inside a Wave Terminal block, which sets WAVETERM_TABID automatically.
  2. Verify the variable with `echo $WAVETERM_TABID`; if empty, re-open a new Wave block or check Wave's terminal env injection settings.
  3. If invoking programmatically, set WAVETERM_TABID explicitly in the child process environment to a valid tab id.
  4. Update both local and remote wsh binaries to match your Wave Terminal version so env propagation works.

Example fix

// before (external script)
ssh host 'wsh editor notes.md'
// after (run inside a Wave block, or pass env)
ssh host 'WAVETERM_TABID=<tabid> wsh editor notes.md'
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("WAVETERM_TABID") == "" {
    return fmt.Errorf("not running inside a Wave terminal block; WAVETERM_TABID unset")
}

Try / catch

if err := editorRun(cmd, args); err != nil {
    if strings.Contains(err.Error(), "WAVETERM_TABID") {
        // fall back to non-block editing (e.g. exec $EDITOR)
    }
}

Prevention

When it happens

Trigger: Running `wsh editor <file>` when WAVETERM_TABID is empty — typically when the command is invoked from a shell that is not a Wave terminal block (plain SSH session, tmux, IDE terminal, CI shell) or from a Wave version that predates tab-id env injection.

Common situations: Developers run wsh from an external terminal or over SSH instead of inside a Wave block; the env var was stripped by sudo/tmux/clear-env; an old wsh binary is installed on the remote side and never received the variable.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/e6ef4f1b97bdfd24. Report an issue: GitHub.