MemPalace/mempalace · error · ValueError

{field_name} contains null bytes

Error message

{field_name} contains null bytes

What it means

Raised by sanitize_name() when the supplied name contains a NUL byte (\x00). NUL bytes are invalid in filesystem paths and terminate C strings in underlying storage engines (SQLite, ChromaDB), so any name containing one is rejected before storage. This usually indicates corrupted input or binary data leaking into a text field.

Source

Thrown at mempalace/config.py:92

    """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")

    return value


def sanitize_kg_value(value: str, field_name: str = "value") -> str:
    """Validate a knowledge-graph entity name (subject or object).

    More permissive than sanitize_name — allows punctuation like commas,
    colons, and parentheses that are common in natural-language KG values.
    Only blocks null bytes and over-length strings.

    Not used for wing/room names (which have filesystem constraints) or
    predicates (which should be simple relationship identifiers).
    """

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Strip or reject NUL bytes at the source: name.replace("\x00", "") if lossy cleanup is acceptable
  2. Find where the binary data entered the pipeline (file decode mode, socket read) and fix the decoding
  3. Treat the presence of \x00 in a name as a bug in the upstream producer, not something to sanitize away silently

Example fix

# before
name = raw_bytes.decode("utf-8", errors="ignore")   # may retain \x00

# after
name = raw_bytes.decode("utf-8", errors="strict").replace("\x00", "")
Defensive patterns

Strategy: validation

Validate before calling

# Reject binary-contaminated names before the call:
if not isinstance(name, str) or "\x00" in name:
    raise SystemExit("name must be NUL-free text")

Type guard

def is_nul_free(value: str) -> bool:
    return isinstance(value, str) and "\x00" not in value

Try / catch

try:
    safe = sanitize_name(name)
except ValueError as exc:
    if "null bytes" in str(exc):
        safe = sanitize_name(name.replace("\x00", ""))
    else:
        raise

Prevention

When it happens

Trigger: Passing a name containing \x00 — typically from decoding binary data, truncated/corrupted UTF-8, or a test fixture embedding raw bytes.

Common situations: Reading names from a binary or mis-decoded source; data corrupted in transit; fuzzing/security testing payloads embedded in tool arguments.

Related errors


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/727de785781f4ec9. Report an issue: GitHub.