Mintplex-Labs/anything-llm · warning

Would exceed ${CHAR_LIMIT} char limit

Error message

Would exceed ${CHAR_LIMIT} char limit

What it means

Returned (HTTP 400) by POST /api/memories when appending the trimmed entry would push the combined length of all existing entries plus delimiters past CHAR_LIMIT (5000, server.js:17). MEMORY.md is injected into the pi agent's system context, so its total size is capped. The append is rejected atomically — nothing is written and the file is left unchanged.

Source

Thrown at open-computer/services/memory-manager/server.js:65

// --- API Routes ---

app.get("/api/memories", (_req, res) => {
  res.json({ entries: readEntries(MEMORY_FILE) });
});

app.get("/api/user", (_req, res) => {
  res.json({ entries: readEntries(USER_FILE) });
});

app.post("/api/memories", (req, res) => {
  const { entry } = req.body;
  if (!entry || !entry.trim()) return res.status(400).json({ error: "Empty entry" });
  const entries = readEntries(MEMORY_FILE);
  entries.push(entry.trim());
  const combined = entries.join(` ${DELIMITER} `);
  if (combined.length > CHAR_LIMIT) {
    return res.status(400).json({ error: `Would exceed ${CHAR_LIMIT} char limit` });
  }
  writeEntries(MEMORY_FILE, entries);
  res.json({ entries });
});

app.delete("/api/memories/:index", (req, res) => {
  const entries = readEntries(MEMORY_FILE);
  const idx = parseInt(req.params.index, 10);
  if (idx < 0 || idx >= entries.length) return res.status(404).json({ error: "Not found" });
  entries.splice(idx, 1);
  writeEntries(MEMORY_FILE, entries);
  res.json({ entries });
});

app.post("/api/user", (req, res) => {
  const { entry } = req.body;
  if (!entry || !entry.trim()) return res.status(400).json({ error: "Empty entry" });
  const entries = readEntries(USER_FILE);

View on GitHub (pinned to 3aec848f28)

Solutions

  1. Shorten or summarize the new entry so the combined total fits under 5000 chars
  2. DELETE /api/memories/:index to prune stale entries first, then retry the POST
  3. Compute the budget client-side first: entries.join(' § ').length + 3 + entry.trim().length must be ≤ 5000
  4. Operators who genuinely need more room can raise CHAR_LIMIT, at the cost of a larger agent system prompt

Example fix

// before
await post('/api/memories', {entry: hugeTranscript}); // 400 Would exceed 5000 char limit

// after: check the budget before posting
const {entries} = await (await fetch(`${BASE}/api/memories`)).json();
const used = entries.join(' § ').length;
const entry = hugeTranscript.slice(0, 5000 - used - 3).trim(); // fit the remaining budget
if (entry) await post('/api/memories', {entry});
Defensive patterns

Strategy: validation

Validate before calling

const {entries} = await (await fetch(`${BASE}/api/memories`)).json();
const used = entries.join(' § ').length; // same DELIMITER + spaces the server joins with
const fits = used + 3 + entry.trim().length <= 5000;
if (!fits) throw new Error('prune old memories first');

Try / catch

try { await post('/api/memories', {entry}); }
catch (e) {
  if (e.status === 400 && /char limit/.test(e.body?.error ?? '')) {
    await pruneOldest(); await post('/api/memories', {entry}); // retry once after pruning
  }
}

Prevention

When it happens

Trigger: POST /api/memories where current entries joined with ' § ' plus the new entry exceeds 5000 chars; posting a long transcript excerpt when MEMORY.md is already near the cap; repeated small additions accumulating to the limit.

Common situations: Pasting whole logs or conversations as a 'memory'; forgetting that the joining delimiter and surrounding spaces count toward the total; agents or scripts appending memories every run until the budget fills.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/3af3e38fe8cfa904. Report an issue: GitHub.