gastownhall/beads · warning · memoryops.ErrValidation
memory key must not be empty
Error message
memory key must not be empty
What it means
ValidateKey requires that an explicitly supplied memory key names something: empty or whitespace-only keys are rejected with memoryops.ErrValidation. Keys that pass are returned UNCHANGED — surrounding space is deliberately preserved because a user may genuinely hold such a key via bd remember --key.
Source
Thrown at internal/memoryapi/memoryapi.go:96
// reading since the command shipped, and the sentinel is what code classifies
// on.
func ValidateContent(content string) error {
if strings.TrimSpace(content) == "" {
return fmt.Errorf("%w: memory content cannot be empty", memoryops.ErrValidation)
}
return nil
}
// ValidateKey checks a key a caller wants to read or remove, and returns it
// UNCHANGED.
//
// Unchanged is the whole point: `bd remember --key` accepts any string, so a
// key differing from another only by surrounding space is a key someone may
// genuinely hold, and trimming it here would answer a different question from
// the one asked. The only rule is that a key has to name something.
func ValidateKey(key string) (string, error) {
if strings.TrimSpace(key) == "" {
return "", fmt.Errorf("%w: memory key must not be empty", memoryops.ErrValidation)
}
return key, nil
}
// ResolveKey answers which key a Remember lands under: the caller's if it gave
// one, otherwise the derivation of the content.
//
// It is one function rather than a derivation at each implementation because
// the ORDER matters and is invisible once it is spelled twice: an explicit key
// is used verbatim even when it is content-shaped, and content is only ever
// derived from when no key was given. The refusal for content that derives to
// nothing lives here too, so a caller cannot get a row under the empty key by
// reaching the write through a body that forgot to check.
func ResolveKey(key, content string) (string, error) {
if err := ValidateContent(content); err != nil {
return "", err
}
if key != "" {View on GitHub (pinned to 71377f2769)
Solutions
- Supply a non-empty key via --key or the key argument.
- Check the variable feeding --key is set and non-blank.
- If unsure of a key, omit --key and let bd derive one from the content.
Example fix
// before
key, err := memoryapi.ValidateKey(os.Args[2]) // may be ""
// after
if strings.TrimSpace(os.Args[2]) == "" {
return fmt.Errorf("--key requires a value")
}
key, err := memoryapi.ValidateKey(os.Args[2]) Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(key) == "" {
return fmt.Errorf("--key requires a non-empty value")
} Type guard
func hasKey(s string) bool { return strings.TrimSpace(s) != "" } Try / catch
key, err := memoryapi.ValidateKey(providedKey)
if err != nil {
if errors.Is(err, memoryops.ErrValidation) {
return fmt.Errorf("provide --key or omit it to derive from content")
}
return err
} Prevention
- Never feed unset variables into --key without checking.
- Prefer letting bd derive the key when unsure.
- Keep key arguments quoted in shell scripts.
When it happens
Trigger: Calling ValidateKey("") or a whitespace-only string; bd remember --key " "; ResolveKey delegating to ValidateKey with a blank explicit key.
Common situations: --key flag fed from an unset shell variable; script passing an empty placeholder key; copy-pasted key that lost its content in transit.
Related errors
- memory content cannot be empty
- %s cannot be empty
- no rules to compact
- could not generate key from content; use --key to specify on
- %w: apply batch requires at least one item
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/819162b8edf07ed9.
Report an issue: GitHub.