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

  1. Check the server's generated-files storage directory actually contains the filename
  2. Align the storage path configuration across all instances serving these URLs
  3. Regenerate the file by re-running the chat request that produced it
  4. 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

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


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