MemPalace/mempalace · error · ValueError

content exceeds maximum length of {max_length} characters

Error message

content exceeds maximum length of {max_length} characters

What it means

Raised by sanitize_content() when drawer/diary content exceeds max_length characters (default 100,000). Verbatim storage means content is never silently truncated — an over-long payload would bloat a single drawer beyond its intended granularity, so it is rejected and the caller is expected to chunk it first.

Source

Thrown at mempalace/config.py:215


def sanitize_iso_date(value, field_name: str = "date"):
    """Backward-compatible wrapper for ISO temporal validation.

    Historically this accepted only full dates. It now also accepts canonical
    UTC datetimes, but the old name is kept so existing imports continue to
    work.
    """

    return sanitize_iso_temporal(value, field_name)


def sanitize_content(value: str, max_length: int = 100_000) -> str:
    """Validate drawer/diary content length."""
    if not isinstance(value, str) or not value.strip():
        raise ValueError("content must be a non-empty string")
    if len(value) > max_length:
        raise ValueError(f"content exceeds maximum length of {max_length} characters")
    if "\x00" in value:
        raise ValueError("content contains null bytes")
    return strip_lone_surrogates(value)


DEFAULT_PALACE_PATH = os.path.expanduser("~/.mempalace/palace")
DEFAULT_COLLECTION_NAME = "mempalace_drawers"
DEFAULT_BACKEND = "chroma"
DEFAULT_MILVUS_CONSISTENCY_LEVEL = "Strong"
_MILVUS_CONSISTENCY_LEVELS = {
    "strong": "Strong",
    "session": "Session",
    "bounded": "Bounded",
    "eventually": "Eventually",
}

# How many timestamped palace backups to retain before the oldest are
# pruned. Applies to the accumulating backups written by ``mempalace

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Chunk the content into multiple drawers below the limit (split on paragraph/session boundaries to keep chunks coherent)
  2. Check size before the call: len(content) <= 100_000 (or the max_length you pass)
  3. Pass a larger max_length explicitly only if your use case truly needs one huge drawer

Example fix

# before
save_drawer(wing, room, huge_text)   # >100k chars

# after
for i in range(0, len(huge_text), 90_000):
    save_drawer(wing, room, huge_text[i:i+90_000])
Defensive patterns

Strategy: validation

Validate before calling

MAX = 100_000  # keep in sync with the default, or your explicit max_length
CHUNK = 90_000
chunks = [content[i:i + CHUNK] for i in range(0, len(content), CHUNK)] or [""]
# write each chunk as its own drawer

Type guard

def content_within_limit(content: str, max_length: int = 100_000) -> bool:
    return isinstance(content, str) and 0 < len(content) <= max_length

Try / catch

try:
    safe = sanitize_content(content)
except ValueError as exc:
    if "maximum length" in str(exc):
        for chunk in split_paragraph_boundaries(content, 90_000):
            save_drawer(wing, room, chunk)
    else:
        raise

Prevention

When it happens

Trigger: Calling a drawer/diary write API with a document longer than the limit — e.g. saving a whole day's transcript, a large log file, or concatenated sessions as one content string (default limit 100k chars).

Common situations: Bulk-importing large files without chunking; hooks accumulating an entire long session; users pasting a whole book chapter; custom callers raising the limit elsewhere but hitting the default.

Related errors


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