wavetermdev/waveterm · error

no WAVETERM_TABID env var set

Error message

no WAVETERM_TABID env var set

What it means

`wsh secret ui` opens the secrets UI block in the Wave terminal via RPC, which needs the current tab id. The CLI derives it from the WAVETERM_TABID environment variable injected by Wave into every terminal block. If that variable is absent, wsh has no way to know where to create the block, so it fails before making any RPC.

Source

Thrown at cmd/wsh/cmd/wshcmd-secret.go:181

	secrets := map[string]*string{name: nil}
	err := wshclient.SetSecretsCommand(RpcClient, secrets, &wshrpc.RpcOpts{Timeout: 2000})
	if err != nil {
		return fmt.Errorf("deleting secret: %w", err)
	}

	WriteStdout("secret deleted: %s\n", name)
	return nil
}

func secretUiRun(cmd *cobra.Command, args []string) (rtnErr error) {
	defer func() {
		sendActivity("secret", rtnErr == nil)
	}()

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

	wshCmd := &wshrpc.CommandCreateBlockData{
		TabId: tabId,
		BlockDef: &waveobj.BlockDef{
			Meta: map[string]interface{}{
				waveobj.MetaKey_View: "waveconfig",
				waveobj.MetaKey_File: "secrets",
			},
		},
		Magnified: secretUiMagnified,
		Focused:   true,
	}

	_, err := wshclient.CreateBlockCommand(RpcClient, *wshCmd, &wshrpc.RpcOpts{Timeout: 2000})
	if err != nil {
		return fmt.Errorf("opening secrets UI: %w", err)
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Run `wsh secret ui` from inside a Wave Terminal block so WAVETERM_TABID is injected.
  2. Check `echo $WAVETERM_TABID`; if empty, re-open a Wave terminal block instead of a plain terminal.
  3. If using sudo/env -i, preserve the var: `sudo --preserve-env=WAVETERM_TABID wsh secret ui`.
  4. On remote hosts, use `wsh setenv`/conn-related tooling or run the command locally in Wave instead.

Example fix

// before (plain shell)
$ wsh secret ui
// after (run inside a Wave terminal block where the var is present)
$ echo $WAVETERM_TABID   # e.g. 8f2c...
$ wsh secret ui
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("WAVETERM_TABID") == "" {
    return errors.New("run from inside a Wave terminal block (WAVETERM_TABID not set)")
}

Try / catch

if err := run(); err != nil {
    if strings.Contains(err.Error(), "WAVETERM_TABID") {
        fmt.Fprintln(os.Stderr, "Hint: open a Wave terminal block and retry")
    }
}

Prevention

When it happens

Trigger: Running `wsh secret ui` in an environment where WAVETERM_TABID is unset: a plain OS shell (ssh session, CI runner, bare terminal), or inside a Wave block where the env var was stripped (e.g. via `env -i`, sudo, or a nested shell that sanitized the environment).

Common situations: SSH-ing into a remote host and running wsh there; scripts that sanitize env before exec; older Wave versions or plain terminals that don't inject WAVETERM_TABID.

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/0016574448dd1795. Report an issue: GitHub.