MemPalace/mempalace · error · ValueError
{field_name} must be a non-empty string
Error message
{field_name} must be a non-empty string What it means
Raised by sanitize_name() when the wing/room/entity name is not a string, or is a string that is empty or whitespace-only after potential stripping. Names become directory/collection identifiers, so a blank name would create an unusable path. Every MCP write tool and most CLI write paths route names through this validator.
Source
Thrown at mempalace/config.py:79
The same rule is applied by ``init`` when persisting `topics_by_wing`
and when writing `mempalace.yaml`, so the miner's lookup matches at
mine time regardless of the source dirname.
Leading/trailing separators are stripped so a path-encoded dirname like
``-home-user-proj`` yields ``home_user_proj`` rather than a leading-
underscore slug that ``sanitize_name`` (and thus the MCP write tools)
would reject.
"""
return name.lower().replace(" ", "_").replace("-", "_").strip("_")
def sanitize_name(value: str, field_name: str = "name") -> str:
"""Validate and sanitize a wing/room/entity name.
Raises ValueError if the name is invalid.
"""
if not isinstance(value, str) or not value.strip():
raise ValueError(f"{field_name} must be a non-empty string")
value = value.strip()
if len(value) > MAX_NAME_LENGTH:
raise ValueError(f"{field_name} exceeds maximum length of {MAX_NAME_LENGTH} characters")
# Block path traversal
if ".." in value or "/" in value or "\\" in value:
raise ValueError(f"{field_name} contains invalid path characters")
# Block null bytes
if "\x00" in value:
raise ValueError(f"{field_name} contains null bytes")
# Enforce safe character set
if not _SAFE_NAME_RE.match(value):
raise ValueError(f"{field_name} contains invalid characters")
View on GitHub (pinned to 06cb6987f0)
Solutions
- Supply a real, non-empty name for the field identified in the message (field_name tells you which argument)
- In calling code, check the value before the call: if not (isinstance(n, str) and n.strip())
- Fix shell scripts to fail fast on unset variables (set -u / ${NAME:?})
Example fix
# before
wing = os.environ.get("WING", "") # empty when unset
create_wing(wing)
# after
wing = os.environ["WING"] # fails fast, or validate first
if not wing.strip(): raise SystemExit("WING name required")
create_wing(wing) Defensive patterns
Strategy: type-guard
Validate before calling
# Before any name-taking call:
if not isinstance(name, str) or not name.strip():
raise SystemExit("name must be a non-empty string") Type guard
def is_valid_name(value) -> bool:
return isinstance(value, str) and bool(value.strip()) Try / catch
try:
safe = sanitize_name(name, "wing")
except ValueError as exc:
if "non-empty" in str(exc):
name = fallback_name # e.g. "unnamed"
else:
raise Prevention
- Fail fast on unset shell variables (set -u) in scripts that pass names
- Check MCP tool arguments for missing/None name fields before sending
- Validate names at your app boundary, not inside storage code
When it happens
Trigger: Calling a write tool or CLI command with name=None, name=123 (non-string), name="" or name=" " — e.g. a script passing an unset environment variable or an LLM tool call omitting the name field so it arrives as empty.
Common situations: Unset shell variable expanding to empty string ($NAME with NAME undefined); MCP client sending null for an omitted optional-looking field; whitespace-only name pasted from a form; programmatic callers passing an int id.
Related errors
- {field_name} exceeds maximum length of {MAX_NAME_LENGTH} cha
- {field_name} contains invalid path characters
- {field_name} contains null bytes
- {field_name} contains invalid characters
- pass inline text or a file, not both
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/80d91a94ceddc301.
Report an issue: GitHub.