wavetermdev/waveterm · error

No appropriate secret manager found, cannot set secrets

Error message

No appropriate secret manager found, cannot set secrets

What it means

Before writing a secret, the CLI queries the Linux storage backend and refuses to proceed if it reports `basic_text` (plaintext file fallback) or `unknown`. Wave only allows secrets to be stored in a real secret manager (e.g. gnome-keyring/secret-service or KWallet); this prevents silently writing credentials to an unencrypted file or an undetectable store. Note the check only runs on this set path — it reflects the daemon's evaluation of the local environment.

Source

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

	parts := strings.SplitN(args[0], "=", 2)
	if len(parts) != 2 {
		return fmt.Errorf("invalid format: expected [name]=[value]")
	}

	name := parts[0]
	value := parts[1]

	if name == "" {
		return fmt.Errorf("secret name cannot be empty")
	}

	backend, err := wshclient.GetSecretsLinuxStorageBackendCommand(RpcClient, &wshrpc.RpcOpts{Timeout: 2000})
	if err != nil {
		return fmt.Errorf("checking secret storage backend: %w", err)
	}

	if backend == "basic_text" || backend == "unknown" {
		return fmt.Errorf("No appropriate secret manager found, cannot set secrets")
	}

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

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

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

	names, err := wshclient.GetSecretsNamesCommand(RpcClient, &wshrpc.RpcOpts{Timeout: 2000})

View on GitHub (pinned to a4447c1563)

Solutions

  1. Install and start a secret service: e.g. `sudo apt install gnome-keyring` and ensure `dbus-run-session`/secret-service is available in your session (or use KWallet on KDE).
  2. Unlock your keyring (log into the desktop session, or unlock gnome-keyring via `echo -n 'pass' | gnome-keyring-daemon --unlock`).
  3. For headless/CI use, run secrets through a Wave instance on a machine with a working keyring, or store configuration values in wconfig files instead of the secrets store.
  4. If a keyring is actually running but reported unknown, update Wave Terminal — backend detection may not support your secret manager version.
Defensive patterns

Strategy: validation

Validate before calling

backend, err := wshclient.GetSecretsLinuxStorageBackendCommand(RpcClient, &wshrpc.RpcOpts{Timeout: 2000})
if err != nil { return err }
if backend == "basic_text" || backend == "unknown" {
    return fmt.Errorf("install/start gnome-keyring or KWallet before setting secrets")
}

Type guard

func hasSecureSecretBackend(backend string) bool {
    return backend != "basic_text" && backend != "unknown" && backend != ""
}

Prevention

When it happens

Trigger: Running `wsh secret set NAME=VALUE` on a Linux system where no proper secret service is available: headless servers, containers, WSL without secret-service, or desktops where the keyring is locked/uninstalled, so the daemon reports basic_text or unknown.

Common situations: CI runners and Docker images without D-Bus/keyring; fresh Linux installs without gnome-keyring; SSH sessions where the user keyring session isn't unlocked; WSL2 setups lacking secret-service providers like gnome-keyring with dbus.

Related errors


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