wavetermdev/waveterm · error
error setting secret %q: %w
Error message
error setting secret %q: %w
What it means
SetSecretsCommand calls secretstore.SetSecret for non-nil values to store or update a secret. A backend write failure is wrapped as "error setting secret %q". Because iteration order over the map is not deterministic, a failure aborts remaining entries and which secrets were applied may vary between runs.
Source
Thrown at pkg/wshrpc/wshserver/wshserver.go:1507
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
}
func (ws *WshServer) JobCmdExitedCommand(ctx context.Context, data wshrpc.CommandJobCmdExitedData) error {
return jobcontroller.HandleCmdJobExited(ctx, data.JobId, data)
}
View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped cause to identify the backend failure mode.
- Unlock the keychain / start the secret service and retry.
- Apply secrets one at a time so partial success is deterministic.
- Reduce secret size or check backend storage permissions if limits/permissions are implicated.
Example fix
// before
wshclient.SetSecretsCommand(ctx, map[string]*string{"a": &a, "b": &b}) // fails partway, nondeterministic
// after
for name, val := range secrets {
if err := wshclient.SetSecretsCommand(ctx, map[string]*string{name: val}); err != nil {
return fmt.Errorf("failed on %q: %w", name, err)
}
} Defensive patterns
Strategy: validation
Validate before calling
const maxSecretLen = 8 * 1024 // conservative backend limit
if value != nil && len(*value) > maxSecretLen {
return fmt.Errorf("secret %q too large for backend storage", name)
} Try / catch
err := wshclient.SetSecretsCommand(ctx, map[string]*string{name: &value})
if err != nil && strings.Contains(err.Error(), "error setting secret") {
// prompt user to unlock keychain or fall back to prompt-on-use instead of storing
} Prevention
- Write secrets one at a time; map iteration order makes batched writes non-deterministic on failure.
- Keep secret values small; large values may exceed backend limits.
- Ensure an unlocked keyring/secret service exists before automated writes.
- Handle user-denied keychain prompts (macOS) as a retry-able condition.
When it happens
Trigger: SetSecretsCommand with {name: &value} while the secret backend rejects the write — locked keychain, full/immutable backend storage, item size limits, or missing secret service on Linux.
Common situations: Storing tokens over a remote/headless session without a keyring; keychain prompting denied by the user; read-only fallback storage file; very large secret values exceeding backend limits.
Related errors
- error getting secret %q: %w
- error getting secret names: %w
- error deleting secret %q: %w
- setting secret: %w
- listing secrets: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/22c23038f4f9c594.
Report an issue: GitHub.