Mintplex-Labs/anything-llm · warning
Memory not found.
Error message
Memory not found.
What it means
404 from the validateMemoryOwner middleware. In multi-user mode the lookup adds clause.userId = user.id, so a memory owned by another user is deliberately indistinguishable from a missing one — both yield null from Memory.get and 404. Also fires for non-numeric ids (Number() → NaN never matches) and, subtly, when Memory.get swallows a DB error and returns null.
Source
Thrown at server/endpoints/memory.js:32
return response.status(403).json({ error: "Personalization is disabled." });
next();
}
/**
* Loads the memory by :memoryId and, in multi-user mode, scopes the query to the requester's userId.
* A memory owned by another user returns null here and is indistinguishable from "not found" — 404 either way.
*/
async function validateMemoryOwner(request, response, next) {
try {
const clause = { id: Number(request.params.memoryId) };
if (response.locals.multiUserMode) {
const user = await userFromSession(request, response);
clause.userId = user?.id ?? null;
}
const memory = await Memory.get(clause);
if (!memory)
return response.status(404).json({ error: "Memory not found." });
next();
} catch (e) {
console.error(e);
return response.sendStatus(500);
}
}
function memoryEndpoints(app) {
if (!app) return;
app.get(
"/workspaces/:slug/memories",
[
validatedRequest,
flexUserRoleValid([ROLES.all]),
memoryFeatureEnabled,
validWorkspaceSlug,View on GitHub (pinned to 3aec848f28)
Solutions
- Re-fetch the memory list (GET /memories / workspace memories) and use an id from the fresh response
- Confirm you are authenticated as the owning user in multi-user mode
- Treat 404 as 'gone or not yours' — do not blindly retry
- If every id 404s at once, suspect DB connectivity: Memory.get masks errors as null, so check server logs
Example fix
// before
await fetch(`/memories/${memoryId}`, { method: 'PUT', ... });
// after
const fresh = (await (await fetch('/memories')).json()).memories ?? [];
if (!fresh.some((m) => m.id === Number(memoryId))) { refreshUI(); return; }
await fetch(`/memories/${memoryId}`, { method: 'PUT', ... }); Defensive patterns
Strategy: validation
Validate before calling
// Only mutate ids present in the freshest list the caller can see
const fresh = await (await fetch('/memories')).json();
const mine = new Set((fresh.memories ?? []).map((m) => m.id));
if (!mine.has(Number(memoryId))) throw new Error('Memory is gone or not owned by this user'); Type guard
function isOwnedMemoryId(list, id) {
return typeof id === 'number' && Number.isInteger(id)
&& list.some((m) => m.id === id);
} Prevention
- Never cache memory ids long-term; re-fetch before every mutation
- In multi-user mode, remember 404 also means 'owned by someone else'
- A sudden 404 across all ids suggests a DB issue (Memory.get masks errors as null) — check logs
When it happens
Trigger: Any /memories/:memoryId route where the id does not exist, was deleted, belongs to a different user (multi-user mode), is non-numeric, or the Prisma query errored (Memory.get's catch returns null).
Common situations: Stale UI after the memory was deleted from another tab/device; reusing an id captured under a different account; session switched mid-flow; DB outage masquerading as 404.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- File not found or access denied
- Image not found or access denied
- Workspace not found
- Could not load ${this.model} into Foundry Local: ${error}
- no pending help request with that id
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/f0bd783042ab10d0.
Report an issue: GitHub.