HKUDS/Vibe-Trading · error · ValueError
memory name must not be empty or whitespace-only
Error message
memory name must not be empty or whitespace-only
What it means
PersistentMemory.add rejects a memory name that is empty after stripping. Names generate the storage slug, so a blank name cannot be persisted and is rejected before type checks or slug generation.
Source
Thrown at agent/src/memory/persistent.py:497
def add(
self,
name: str,
content: str,
memory_type: str = "project",
description: str = "",
) -> Optional[Path]:
"""Save a new memory entry and update the index."""
if _is_quality_enabled() and self.is_duplicate(name, description, content):
logger.debug(
"Duplicate memory write blocked within %.0fs window: %s",
DEDUP_WINDOW_SECONDS,
name,
)
return None
stripped_name = name.strip()
if not stripped_name:
raise ValueError("memory name must not be empty or whitespace-only")
if memory_type not in MEMORY_TYPES:
raise ValueError(f"memory_type must be one of: {', '.join(MEMORY_TYPES)}")
slug = _SLUG_DISALLOWED_RE.sub("_", stripped_name.lower())[:60]
if slug.strip("_") == "":
digest = hashlib.sha256(stripped_name.encode("utf-8")).hexdigest()[:6]
slug = f"{slug}_{digest}" if slug else digest
from src.config.accessor import get_env_config
if get_env_config().memory.hierarchy_enabled:
from src.memory.hierarchy import MemoryHierarchy
hierarchy = MemoryHierarchy(self._dir)
# route_entry() treats its second argument as the leaf filename
# verbatim, so the ".md" has to be here: a bare slug wrote entries
# with no suffix, and every scan filters on suffix == ".md", which
# made them invisible to list_entries() and find(). The category
# directory already carries the type, and the name must match what
# recover_extensionless_entries() renames orphans to, or the sameView on GitHub (pinned to 80ffdda44c)
Solutions
- Validate the name is non-blank before calling add
- Skip or log-and-continue records with blank names in batch loops
- Default to a derived name (e.g. timestamp or content digest) when the source field is missing
Example fix
# before
mem.add(name=user_title, memory_type="observation", content=text)
# after
if user_title and user_title.strip():
mem.add(name=user_title.strip(), memory_type="observation", content=text) Defensive patterns
Strategy: validation
Validate before calling
name = (name or '').strip()
if not name:
log.warning('skipping memory with blank name'); return None
mem.add(name=name, memory_type=memory_type, content=content) Type guard
def is_valid_memory_name(n) -> bool:
return isinstance(n, str) and bool(n.strip()) Try / catch
try:
mem.add(name=name, memory_type=memory_type, content=content)
except ValueError as exc:
if 'must not be empty' in str(exc):
mem.add(name=derived_fallback_name, memory_type=memory_type, content=content) Prevention
- Validate generated/LLM-provided names before persisting
- Skip-and-log blank records in batch ingestion
- Default to a deterministic fallback name (digest/timestamp)
When it happens
Trigger: Calling add(name="", ...), add(name=" ", ...), or add(name=None) where None is stringified to a blank; programmatic callers passing unvalidated identifiers.
Common situations: Batch ingestion loops where some records lack a name field, LLM/tool output used directly as memory names, or whitespace names from copy-paste.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- title is required
- thesis is required
- memory_type must be one of: {', '.join(MEMORY_TYPES)}
- audit rows require criterion_id and result
- invalid alpha_id
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/47b063602c870198.
Report an issue: GitHub.