MemPalace/mempalace · error · ValueError
{field_name} exceeds maximum length of {_MAX_ROUTING_LENGTH}
Error message
{field_name} exceeds maximum length of {_MAX_ROUTING_LENGTH} characters What it means
ValueError raised by _sanitize_routing() when a routing field exceeds _MAX_ROUTING_LENGTH (256 characters). Routing fields become part of stream/room identifiers, so unbounded values are rejected to keep names and any derived paths/files manageable.
Source
Thrown at mempalace/logstream.py:114
return f"{prefix}_{stamp}_{secrets.token_hex(6)}"
def _sanitize_routing(value, field_name: str, required: bool = True) -> Optional[str]:
"""Validate a short routing field (stream, room, agent, correlation_id).
Streams may contain ``/`` (``project/mempalace``), so this is looser
than ``config.sanitize_name`` — but null bytes, control characters,
and over-length values are still rejected.
"""
if value is None or value == "":
if required:
raise ValueError(f"{field_name} must be a non-empty string")
return None
if not isinstance(value, str) or not value.strip():
raise ValueError(f"{field_name} must be a non-empty string")
value = strip_lone_surrogates(value.strip())
if len(value) > _MAX_ROUTING_LENGTH:
raise ValueError(f"{field_name} exceeds maximum length of {_MAX_ROUTING_LENGTH} characters")
if any(ord(ch) < 0x20 or ch == "\x7f" for ch in value):
raise ValueError(f"{field_name} contains control characters")
return value
def _sanitize_event_type(value) -> str:
if not isinstance(value, str) or not value.strip():
raise ValueError("type must be a non-empty string")
value = value.strip()
if not _EVENT_TYPE_RE.match(value):
raise ValueError(
f"type={value!r} is not a valid event type "
"(lowercase letters, digits, '.', '_', '-'; max 64 chars)"
)
return value
def _sanitize_status(value) -> Optional[str]:View on GitHub (pinned to 06cb6987f0)
Solutions
- Shorten the value to <= 256 chars — routing fields are names, not payloads
- Move long content into the event payload/body fields, which are not routing-limited
- If generating names programmatically, hash the long part: hashlib.sha256(x.encode()).hexdigest()[:16]
Example fix
# before
events.emit(type="x", stream="project/" + "a" * 400, room="r") # exceeds maximum length of 256
# after
import hashlib
short = hashlib.sha256(long_name.encode()).hexdigest()[:16]
events.emit(type="x", stream=f"project/{short}", room="r") Defensive patterns
Strategy: validation
Validate before calling
MAX_ROUTING = 256
def routing_ok(value) -> bool:
return isinstance(value, str) and 0 < len(value.strip()) <= MAX_ROUTING Try / catch
try:
events.emit(type=t, stream=s, room=r)
except ValueError as e:
if "exceeds maximum length" in str(e):
s = s[:MAX_ROUTING]
events.emit(type=t, stream=s, room=r)
else:
raise Prevention
- Keep routing fields as short stable names, never payloads or paths
- Hash long generated identifiers to a fixed length
- Assert length limits in tests for anything user-supplied
When it happens
Trigger: Passing a long descriptive string, a full sentence, or concatenated identifiers (e.g. 'wing/room/drawer/uuid/uuid/uuid...') as stream, room, agent, or correlation_id with length > 256.
Common situations: Stuffing a path or message snippet into correlation_id; auto-generated names that concatenate many ids; pasting a whole line of output into a routing field by mistake.
Related errors
- {field_name} must be a non-empty string
- {field_name} exceeds maximum length of {MAX_NAME_LENGTH} cha
- content exceeds maximum length of {max_length} characters
- {field_name} contains control characters
- type must be a non-empty string
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/54b524e392fa166a.
Report an issue: GitHub.