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
- Pre-check WorkspaceParsedFiles.get({ id, workspaceId, ...(user ? { userId: user.id } : {}) }) returns a row before calling
- Never re-invoke with the same fileId after any attempt - the row is deleted in finally
- Re-upload the source file to create a fresh parsed-file record if the row is gone
- 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
- Treat the call as one-shot: the parsed-file row is deleted in finally, successful or not
- Disable the UI action while a job is pending to prevent double submission
- Verify id + userId + workspaceId match before scheduling the job
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
- Bad Request
- Failed to create workspace
- No file location in metadata
- No workspace found or could be created.
- Source file not found
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)