MemPalace/mempalace · warning · ValueError
request body too large
Error message
request body too large
What it means
ValueError('request body too large') raised in the daemon's HTTP handler (mempalace/daemon.py:938) when Content-Length exceeds MAX_BODY_BYTES. The cap bounds request memory use per authenticated request; the connection body is never read past the check. Like 208, this originates in the server and surfaces to a client as a 400 response with this message.
Source
Thrown at mempalace/daemon.py:938
def log_message(self, fmt, *args): # pragma: no cover - stdlib access logging noise
return
def _authorized(self) -> bool:
auth = self.headers.get("Authorization")
if auth and secrets.compare_digest(auth, f"Bearer {token}"):
return True
_json_response(self, 401, {"error": "unauthorized"})
return False
def _read_json(self) -> dict[str, Any]:
length = int(self.headers.get("Content-Length", "0") or "0")
# Reject a negative Content-Length explicitly: self.rfile.read(-1)
# would read until the client closes the connection, blocking the
# worker and bypassing the MAX_BODY_BYTES cap (an auth-gated DoS).
if length < 0:
raise ValueError("invalid Content-Length")
if length > MAX_BODY_BYTES:
raise ValueError("request body too large")
raw = self.rfile.read(length)
return json.loads(raw.decode("utf-8")) if raw else {}
def do_GET(self):
if not self._authorized():
return
try:
self._handle_get()
except Exception as exc: # noqa: BLE001 - malformed query/DB error → 400
_json_response(self, 400, {"error": str(exc)})
def _handle_get(self):
parsed = urlparse(self.path)
if parsed.path == "/health":
_json_response(
self,
200,
{View on GitHub (pinned to 06cb6987f0)
Solutions
- Split the payload into smaller submits (chunk the transcript; see mempalace/split_mega_files.py for oversized transcript files).
- Trim needless fields from the payload before submitting.
- If a legitimate workflow needs a bigger cap, raise MAX_BODY_BYTES in daemon.py and restart — recognizing the larger memory commitment per request.
Example fix
# before: one giant submit
client.submit("save", {"content": huge_transcript})
# after: chunked submits
for chunk in chunks(huge_transcript, MAX_CHARS):
client.submit("save", {"content": chunk}) Defensive patterns
Strategy: validation
Validate before calling
import json
from mempalace.daemon import MAX_BODY_BYTES
def fits(body: dict) -> bool:
return len(json.dumps(body).encode("utf-8")) <= MAX_BODY_BYTES Try / catch
try:
resp = client.request("POST", "/jobs", payload)
except DaemonError as exc:
if "too large" in str(exc):
for chunk in split_payload(payload):
client.request("POST", "/jobs", chunk) Prevention
- Chunk large transcripts before submit (see split_mega_files.py).
- Size-check serialized payloads against MAX_BODY_BYTES before sending.
- Keep individual job payloads bounded; batch at the daemon side, not the client side.
When it happens
Trigger: POSTing a large transcript/payload to /jobs (e.g. a whole conversation transcript as one submit) whose serialized JSON exceeds MAX_BODY_BYTES; batching many entries into one request; base64-encoding binary content into a JSON body inflating its size.
Common situations: Hook submits an unusually long session diary; users ingest mega-file transcripts (see split_mega_files.py) in a single call; generation of a huge dedupe key list.
Related errors
- invalid Content-Length
- daemon returned non-JSON response: {raw[:200]!r}
- daemon is not running
- daemon is not running; job {args.job_id} is {job['state']}
- daemon token not found for {palace_path}
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/1925556874ad39a3.
Report an issue: GitHub.