Mintplex-Labs/anything-llm · warning
Not found
Error message
Not found
What it means
Returned (HTTP 404) by DELETE /api/memories/:index when the parsed index is < 0 or >= entries.length — there is no entry at that position in MEMORY.md. Indexes are positions in the entries array read at request time, so any concurrent deletion, regeneration of the file, or stale list in the client shifts them out of range. (Edge case: a non-numeric index parses to NaN, which slips past both range comparisons and silently deletes nothing — always send a base-10 integer.)
Solutions
- Re-GET /api/memories immediately before each delete and use the fresh index
- Treat the 404 as 'already deleted' and refresh your list rather than erroring
- For batch deletes, delete from the highest index to the lowest so earlier splices do not shift pending indexes
- Always send an integer index (parseInt(idx, 10) on the client) — NaN bypasses the guard and deletes nothing
Example fix
// before: indexes computed from a stale snapshot
const {entries} = await get('/api/memories');
for (const i of selected) await del(`/api/memories/${i}`); // 404s as list shrinks
// after: refresh + descending order
for (const i of [...selected].sort((a, b) => b - a)) {
const res = await del(`/api/memories/${i}`);
if (res.status === 404) continue; // someone else already removed it
} Defensive patterns
Strategy: validation
Validate before calling
const {entries} = await (await fetch(`${BASE}/api/memories`)).json();
const idx = Number.parseInt(String(rawIndex), 10);
const valid = Number.isInteger(idx) && idx >= 0 && idx < entries.length;
if (!valid) return refreshList(); Type guard
function isValidMemoryIndex(idx, entries) {
return Number.isInteger(idx) && idx >= 0 && idx < entries.length;
} Try / catch
const res = await del(`${BASE}/api/memories/${idx}`);
if (res.status === 404) return refreshList(); // someone else already deleted it Prevention
- Re-fetch the list immediately before every delete; never trust a stale snapshot
- Batch-delete descending (highest index first) so splices do not shift pending indexes
- Send integer indexes only — non-numeric params bypass the server guard and silently no-op
When it happens
Trigger: DELETE /api/memories/7 when only 3 entries exist; re-deleting an index after another tab or the /api/review script already modified the file; computing indexes from a GET /api/memories snapshot taken before other deletions; sending '2nd' or '1.5' as the index.
Common situations: Two UIs editing memories concurrently (first delete shifts every later index); stale list after the pi review process rewrites MEMORY.md; batch delete loops that do not account for indexes shifting down after each splice.
Related errors
- no pending help request with that id
- Empty entry
- File not found
- File not found in storage
- File not found or access denied
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/547ed31087703cb7.
Report an issue: GitHub.
Appendix: source
Thrown at open-computer/services/memory-manager/server.js:74
});
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);
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(USER_FILE, entries);
res.json({ entries });
});
View on GitHub (pinned to 3aec848f28)