Mintplex-Labs/anything-llm · warning
File not found or access denied
Error message
File not found or access denied
What it means
Returned (HTTP 404) by GET /agent-skills/generated-files/:filename when findFileSource(filename, {user, isMultiUser}) returns null. findFileSource searches (1) workspace chats the requesting user can access under multi-user permissions, then (2) scheduled job runs (single-user mode only). Null means no accessible record references the file — it does not exist in any chat/job, or the current user lacks permission. The 404 deliberately conflates 'missing' and 'denied' to avoid leaking which files exist.
Source
Thrown at server/endpoints/agentFileServer.js:54
if (!filename)
return response.status(400).json({ error: "Filename is required" });
// Validate filename format
const parsed = createFilesLib.parseFilename(filename);
if (!parsed) {
return response
.status(400)
.json({ error: "Invalid filename format" });
}
// Find a chat or scheduled job run that references this file
const fileSource = await findFileSource(filename, {
user,
isMultiUser: multiUserMode(response),
});
if (!fileSource) {
return response.status(404).json({
error: "File not found or access denied",
});
}
// Retrieve the file from storage
const fileData = await createFilesLib.getGeneratedFile(filename);
if (!fileData) {
return response
.status(404)
.json({ error: "File not found in storage" });
}
// Get mime type and set headers for download
const mimeType = createFilesLib.getMimeType(`.${parsed.extension}`);
const safeFilename = createFilesLib.sanitizeFilenameForHeader(
fileSource.displayFilename || filename
);
response.setHeader("Content-Type", mimeType);View on GitHub (pinned to 3aec848f28)
Solutions
- Log in as the user who owns/participates in the chat that generated the file and copy the link from that chat
- Confirm your frontend talks to the same instance (same DB and storage) that generated the file
- Regenerate the artifact from a chat your user can access
- Operators: verify the workspace_chats / job-run records actually reference the filename before assuming a bug
Defensive patterns
Strategy: validation
Validate before calling
// Before sharing a link, confirm the current session can see its source chat
const me = await currentUser();
if (artifact.chatId && !me.accessibleChatIds.includes(artifact.chatId))
throw new Error('this file belongs to a workspace you cannot access'); Try / catch
const res = await fetch(url, {credentials: 'include'});
if (res.status === 404) {
// indistinguishable by design: missing OR denied —
// re-authenticate as the owning user or regenerate the file
} Prevention
- Generate files in chats the consumer user can access when sharing is intended
- Keep frontend and backend on one instance so authorizing records actually exist
- Treat these URLs as per-user secrets; do not persist them in shared documents
When it happens
Trigger: In multi-user mode, requesting a file generated inside another user's workspace chat; using a filename from a different instance (frontend pointing at a backend with another database); the chat that referenced the file was deleted; the session resolves to a different/anonymous user than the one who generated it.
Common situations: Sharing artifact URLs between users (denied by design in multi-user mode); split frontend/backend environments with divergent data; stale links after workspace cleanup; login state confusion where the browser session belongs to a lesser-privileged account.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Image not found or access denied
- Memory not found.
- File not found: ${filename}
- File not found in storage
- Workspace not found
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/57501be947fe2eb4.
Report an issue: GitHub.