Mintplex-Labs/anything-llm · error

File not found

Error message

File not found

What it means

Thrown by WorkspaceParsedFiles.moveToDocumentsAndEmbed when no parsed-file row matches the given id (plus the optional userId filter and workspaceId). The method is one-shot: its finally block deletes the parsed-file row whether embedding succeeds or fails, so a second call with the same fileId always lands here. The throw is caught internally and returned to callers as { success: false, error: "File not found", document: null }, not propagated.

Solutions

  1. Pre-check WorkspaceParsedFiles.get({ id, workspaceId, ...(user ? { userId: user.id } : {}) }) returns a row before calling
  2. Never re-invoke with the same fileId after any attempt - the row is deleted in finally
  3. Re-upload the source file to create a fresh parsed-file record if the row is gone
  4. Pass the correct user context: admin/system paths use user=null to skip the userId filter

Example fix

// before
const result = await WorkspaceParsedFiles.moveToDocumentsAndEmbed(user, fileId, workspace);

// after
const parsed = await WorkspaceParsedFiles.get({
  id: Number(fileId),
  workspaceId: workspace.id,
  ...(user ? { userId: user.id } : {}),
});
if (!parsed) return res.status(404).json({ error: "File not found" });
const result = await WorkspaceParsedFiles.moveToDocumentsAndEmbed(user, fileId, workspace);
Defensive patterns

Strategy: validation

Validate before calling

const parsed = await WorkspaceParsedFiles.get({
  id: Number(fileId),
  workspaceId: workspace.id,
  ...(user ? { userId: user.id } : {}),
});
if (!parsed) return res.status(404).json({ error: "File not found" });
const result = await WorkspaceParsedFiles.moveToDocumentsAndEmbed(user, fileId, workspace);

Try / catch

// The method does not throw; it returns a result object
const { success, error, document } = await WorkspaceParsedFiles.moveToDocumentsAndEmbed(user, fileId, workspace);
if (!success) return res.status(404).json({ error });

Prevention

When it happens

Trigger: Calling moveToDocumentsAndEmbed twice for the same fileId (the first attempt's finally already deleted the row); passing a non-admin user whose id does not match the row's userId; using a fileId from a different workspace; a queued job and a manual API call racing on the same file.

Common situations: Retry logic that resubmits after a failed embed; double-clicked "move to documents" actions; background workers and user-triggered requests processing the same upload; passing admin (user=null) vs uploader contexts inconsistently.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at server/models/workspaceParsedFiles.js:117

    });
    return _sum.tokenCountEstimate || 0;
  },

  /**
   * Moves a parsed file to the documents and embeds it.
   * @param {import("@prisma/client").users | null} user - The user performing the operation.
   * @param {number} fileId - The ID of the parsed file.
   * @param {import("@prisma/client").workspaces} workspace - The workspace the file belongs to.
   * @returns {Promise<{ success: boolean, error: string | null, document: import("@prisma/client").workspace_documents | null }>} The result of the operation.
   */
  moveToDocumentsAndEmbed: async function (user = null, fileId, workspace) {
    try {
      const parsedFile = await this.get({
        id: parseInt(fileId),
        ...(user ? { userId: user.id } : {}),
        workspaceId: workspace.id,
      });
      if (!parsedFile) throw new Error("File not found");

      // Get file location from metadata
      const metadata = safeJsonParse(parsedFile.metadata, {});
      const location = metadata.location;
      if (!location) throw new Error("No file location in metadata");

      // Get file from metadata location
      const sourceFile = path.join(directUploadsPath, path.basename(location));
      if (!fs.existsSync(sourceFile)) throw new Error("Source file not found");

      // Move to custom-documents
      const customDocsPath = path.join(documentsPath, "custom-documents");
      if (!fs.existsSync(customDocsPath))
        fs.mkdirSync(customDocsPath, { recursive: true });

      // Copy the file to custom-documents
      const targetPath = path.join(customDocsPath, path.basename(location));
      fs.copyFileSync(sourceFile, targetPath);

View on GitHub (pinned to 20f6d3546c)