wavetermdev/waveterm · error

error deleting secret

Error message

error deleting secret %q: %w

What it means

SetSecretsCommand treats a nil value in the secrets map as a delete request and calls secretstore.DeleteSecret. Failure to delete is wrapped as "error deleting secret %q". Deletion can fail when the backend cannot remove the item or denies access to the collection.

Solutions

  1. Inspect the wrapped cause to see whether it is access denial or backend unavailability.
  2. Unlock/start the OS keychain service and retry the delete.
  3. On Linux, check the configured storage backend is writable (see GetSecretsLinuxStorageBackendCommand).
  4. Retry the specific failing name; entries processed before the failure were already applied.
Defensive patterns

Strategy: try-catch

Validate before calling

if runtime.GOOS == "linux" {
    if _, err := wshclient.GetSecretsLinuxStorageBackendCommand(ctx); err != nil {
        return fmt.Errorf("cannot delete secret, no writable backend: %w", err)
    }
}

Try / catch

err := wshclient.SetSecretsCommand(ctx, map[string]*string{name: nil})
if err != nil && strings.Contains(err.Error(), "error deleting secret") {
    // keychain locked or item protected; surface to user and retry after unlock
}

Prevention

When it happens

Trigger: SetSecretsCommand with secrets map entry {name: nil} while the keychain is locked, the secret service is unavailable, or the item is write-protected in the backend.

Common situations: Bulk-clearing credentials over SSH on headless Linux (no keyring daemon); keychain ACLs preventing modification; backend file permissions read-only.

Related errors


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

Appendix: source

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

		}
	}
	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 {
		if value == nil {
			err := secretstore.DeleteSecret(name)
			if err != nil {
				return fmt.Errorf("error deleting secret %q: %w", name, err)
			}
		} else {
			err := secretstore.SetSecret(name, *value)
			if err != nil {
				return fmt.Errorf("error setting secret %q: %w", name, err)
			}
		}
	}
	return nil
}

func (ws *WshServer) GetSecretsLinuxStorageBackendCommand(ctx context.Context) (string, error) {
	backend, err := secretstore.GetLinuxStorageBackend()
	if err != nil {
		return "", fmt.Errorf("error getting linux storage backend: %w", err)
	}
	return backend, nil
}

View on GitHub (pinned to a4447c1563)