wavetermdev/waveterm · error

error getting secret %q: %w

Error message

error getting secret %q: %w

What it means

GetSecretsCommand iterates the requested secret names and calls secretstore.GetSecret for each. A storage-layer failure (as opposed to 'not exists', which is normal) is wrapped as "error getting secret %q" naming the offending secret. Wave's secret store is backed by the OS keychain (or a Linux backend), so most failures are keychain/backend level.

Source

Thrown at pkg/wshrpc/wshserver/wshserver.go:1480

func (ws *WshServer) GetTabCommand(ctx context.Context, tabId string) (*waveobj.Tab, error) {
	tab, err := wstore.DBGet[*waveobj.Tab](ctx, tabId)
	if err != nil {
		return nil, fmt.Errorf("error getting tab: %w", err)
	}
	return tab, nil
}

func (ws *WshServer) GetAllBadgesCommand(ctx context.Context) ([]baseds.BadgeEvent, error) {
	return wcore.GetAllBadges(), nil
}

func (ws *WshServer) GetSecretsCommand(ctx context.Context, names []string) (map[string]string, error) {
	result := make(map[string]string)
	for _, name := range names {
		value, exists, err := secretstore.GetSecret(name)
		if err != nil {
			return nil, fmt.Errorf("error getting secret %q: %w", name, err)
		}
		if exists {
			result[name] = value
		}
	}
	return result, nil
}

func (ws *WshServer) GetSecretsNamesCommand(ctx context.Context) ([]string, error) {
	names, err := secretstore.GetSecretNames()
	if err != nil {
		return nil, fmt.Errorf("error getting secret names: %w", err)
	}
	return names, nil
}

func (ws *WshServer) SetSecretsCommand(ctx context.Context, secrets map[string]*string) error {
	for name, value := range secrets {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Read the wrapped cause to identify the backend failure (locked keychain, missing secret service, permission).
  2. On Linux, ensure a secret service is running (gnome-keyring via D-Bus) or configure a working GetSecretsLinuxStorageBackend backend.
  3. Unlock the OS keychain and retry the command.
  4. Retry only the failing name — other names in the request may still resolve.
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: confirm a backend exists before reading secrets (Linux)
if runtime.GOOS == "linux" {
    if _, err := wshclient.GetSecretsLinuxStorageBackendCommand(ctx); err != nil {
        return fmt.Errorf("secret store unavailable: %w", err)
    }
}

Try / catch

secrets, err := wshclient.GetSecretsCommand(ctx, names)
if err != nil {
    var se *storeKeychainError // inspect via errors.As on the wrapped cause if exported
    log.Printf("secret read failed: %v", err)
    // retry per-name to isolate the failing secret
}

Prevention

When it happens

Trigger: GetSecretsCommand with a name whose keychain read fails — locked OS keychain (Linux gnome-keyring/KWallet unavailable or locked, macOS Keychain denying access), backend misconfiguration, or I/O failure in the fallback storage.

Common situations: Running Wave over SSH or headless Linux with no secret service (no D-Bus secret provider); keychain access denied after password change; disk/permission problems on the backend file.

Related errors


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