Mintplex-Labs/anything-llm · warning
File not found in storage
Error message
File not found in storage
What it means
Returned (HTTP 404) by GET /agent-skills/generated-files/:filename when findFileSource DID find an authorizing chat/job record, but createFilesLib.getGeneratedFile(filename) returned null — the database references the file while the storage layer does not have the blob. This is DB/storage desync: authorization succeeded (unlike the 'access denied' 404), the file on disk or in the storage driver is simply gone.
Source
Thrown at server/endpoints/agentFileServer.js:63
}
// 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);
response.setHeader(
"Content-Disposition",
`attachment; filename="${safeFilename}"`
);
response.setHeader("Content-Length", fileData.buffer.length);
response.send(fileData.buffer);
Telemetry.sendTelemetry("agent_generated_file_downloaded", {
type: mimeType,
}).catch(() => {});View on GitHub (pinned to 3aec848f28)
Solutions
- Check the server's generated-files storage directory actually contains the filename
- Align the storage path configuration across all instances serving these URLs
- Regenerate the file by re-running the chat request that produced it
- If storage was intentionally pruned, clean the referencing chat/job rows too so links fail fast with the access-denied 404 instead
Defensive patterns
Strategy: validation
Validate before calling
// Operator-side preflight: the DB row and the stored blob must both exist
const rows = await db.query('select 1 from workspace_chats where history like ?', [`%${filename}%`]);
const onDisk = fs.existsSync(path.join(storageDir, 'generated-files', filename));
if (rows.length && !onDisk) console.warn('orphaned reference:', filename); Try / catch
const res = await fetch(url, {credentials: 'include'});
if (res.status === 404) {
const body = await res.json();
if (body.error === 'File not found in storage')
regenerateArtifact(); // authorization passed; the blob is gone — only regeneration helps
} Prevention
- Back up storage and the database together; never wipe one without the other
- Pin the storage path configuration identically across replicas and environments
- After pruning storage, delete referencing chat/job records in the same change
When it happens
Trigger: The storage directory was pruned or deleted while chat history rows remained; STORAGE_DIR/storage location env differs between the generating and serving instances (common with multiple replicas or after a migration); the file was manually removed from storage; a docker volume was not mounted into the container serving downloads.
Common situations: Wiping storage folders to 'clean up' without clearing chat history; moving deployments to new hosts; replica with a different mounted volume serving a link created by another replica; backup restored for the DB but not the storage volume.
Related errors
- Image not found in storage
- Failed to download file
- File not found: ${filename}
- File not found or access denied
- Flow ${uuid} not found
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/f578c0b7dc51ca5e.
Report an issue: GitHub.