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 same

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Validate the name is non-blank before calling add
  2. Skip or log-and-continue records with blank names in batch loops
  3. 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

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


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/47b063602c870198. Report an issue: GitHub.