Mintplex-Labs/anything-llm · error
Failed to move some files.
Error message
Failed to move some files.
What it means
500 from the Promise.all .catch inside POST /document/move-files (admin/manager). Any individual move promise rejected: fs.rename failed (source missing, destination locked, EXDEV cross-device link) or the guard rejected with 'Invalid file location' because from/to escaped documentsPath. The detailed per-file err is only logged server-side ('Error moving file X to Y:'); the client gets this generic message.
Source
Thrown at server/endpoints/document.js:98
Promise.all(movePromises)
.then(() => {
const unmovableCount = files.length - moveableFiles.length;
if (unmovableCount > 0) {
response.status(200).json({
success: true,
message: `${unmovableCount}/${files.length} files not moved. Unembed them from all workspaces.`,
});
} else {
response.status(200).json({
success: true,
message: null,
});
}
})
.catch((err) => {
console.error("Error moving files:", err);
response
.status(500)
.json({ success: false, message: "Failed to move some files." });
});
} catch (e) {
console.error(e);
response
.status(500)
.json({ success: false, message: "Failed to move files." });
}
}
);
}
module.exports = { documentEndpoints };
View on GitHub (pinned to 3aec848f28)
Solutions
- Check the server console for 'Error moving file <from> to <to>:' lines — they carry the exact errno
- Verify each source still exists under documentsPath and each destination folder exists
- If EXDEV, consolidate document storage onto one filesystem, or replace fs.rename with copy+unlink
- Re-fetch the document list and re-submit only the files that failed
Example fix
// before (server) — one failure aborts the whole batch report
Promise.all(movePromises).then(...).catch(() => response.status(500)...);
// after — settle individually and report partial success
const results = await Promise.allSettled(movePromises);
const failed = results.filter((r) => r.status === 'rejected');
response.status(failed.length === movePromises.length ? 500 : 200)
.json({ success: failed.length === 0, message: failed.length ? `${failed.length} move(s) failed` : null }); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify sources exist and destinations are folders before moving
const docs = await fetchDocumentTree();
for (const { from, to } of files) {
if (!docs.has(from)) throw new Error(`Source missing: ${from}`);
if (!isDirectoryOf(docs, to)) throw new Error(`Destination folder missing: ${to}`);
} Try / catch
try {
const r = await fetch('/document/move-files', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ files }) });
if (r.status === 500) { await refreshDocumentTree(); retryMissing(files); } // reconcile and retry remainder once
} catch (e) { console.error('move failed', e); } Prevention
- Keep documentsPath on a single filesystem to avoid EXDEV on rename
- Re-fetch the document tree before bulk moves to drop vanished files
- Server-side: prefer Promise.allSettled over Promise.all to report partial success
When it happens
Trigger: POST /document/move-files where some from/to path fails isWithin(documentsPath) (traversal), the source file no longer exists, the destination is a directory, or the documents storage spans filesystems so rename(2) returns EXDEV.
Common situations: Two clients moving the same file concurrently (source disappears); storage layout changed so documentsPath now crosses a mount point; unsanitized paths from API callers.
Related errors
- Failed to move files.
- Folder by that name already exists
- Invalid path name
- Invalid folder name.
- Could not find a document by id ${docId}
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/16882bb771448320.
Report an issue: GitHub.