Mintplex-Labs/anything-llm · error · Error

Folder name cannot contain path separators.

Error message

Folder name cannot contain path separators.

What it means

Thrown by moveProcessedDocsToFolder() after normalization when the folder still contains a forward or back slash. AnythingLLM document storage is deliberately a flat two-segment layout (folder/file.json); the file picker, embedding pipeline, and vector cache all assume one level below documentsPath. A nested folder name would create invisible, un-embeddable documents, so separators are hard-rejected. The old /v1/document/upload/:folderName route that accepted URL-encoded separators is now blocked here.

Source

Thrown at server/utils/files/index.js:720

 * @returns {string} the normalized folder name the documents were moved into
 * @throws {Error} if the folder name is empty, escapes basePath, or is nested
 */
function moveProcessedDocsToFolder(
  documents = [],
  folderName = "",
  basePath = documentsPath
) {
  const folder = normalizePath(folderName);
  if (!folder) throw new Error("Invalid folder name.");

  // Deliberate: document storage is exactly two segments (`folder/file.json`)
  // and docpath, the embedding pipeline and the vector cache all assume that
  // shape. A nested folder name would produce documents that the file picker
  // (which only enumerates one level below documentsPath) cannot see and that
  // cannot be embedded. /v1/document/upload/:folderName historically accepted
  // a URL-encoded separator here; that is now rejected.
  if (folder.includes("/") || folder.includes("\\"))
    throw new Error("Folder name cannot contain path separators.");

  const targetFolderPath = path.join(basePath, folder);
  if (!isWithin(path.resolve(basePath), path.resolve(targetFolderPath)))
    throw new Error("Invalid folder name.");
  if (!fs.existsSync(targetFolderPath))
    fs.mkdirSync(targetFolderPath, { recursive: true });

  for (const doc of documents) {
    const currentFolder = path.dirname(doc.location);
    if (currentFolder === folder) continue;

    const sourcePath = path.join(basePath, normalizePath(doc.location));
    const destinationPath = path.join(
      targetFolderPath,
      path.basename(doc.location)
    );

    if (!isWithin(basePath, sourcePath) || !isWithin(basePath, destinationPath))

View on GitHub (pinned to 526360e320)

Solutions

  1. Send a single path segment as folderName (letters, digits, dash, underscore only).
  2. If you need hierarchy, flatten it client-side into a unique slug (e.g. 'projects-2024') or use a workspace instead of a nested folder.
  3. Strip or reject slashes at the API boundary before reaching the storage layer.
  4. Update any client that historically URL-encoded a separator into :folderName.

Example fix

// before
moveProcessedDocsToFolder(docs, 'my/sub/folder'); // throws

// after
const slug = folderName.replace(/[^a-zA-Z0-9._-]/g, '-');
moveProcessedDocsToFolder(docs, slug);
Defensive patterns

Strategy: validation

Validate before calling

if (folderName.includes('/') || folderName.includes('\\'))
  return res.status(400).json({ error: 'Folder name cannot contain path separators.' });

Type guard

function isSingleSegment(v): v is string {
  return typeof v === 'string' && !v.includes('/') && !v.includes('\\');
}

Try / catch

try {
  await moveProcessedDocsToFolder(docs, folderName);
} catch (e) {
  if (e.message.startsWith('Folder name cannot contain'))
    return res.status(400).json({ error: e.message });
  throw e;
}

Prevention

When it happens

Trigger: Calling moveProcessedDocsToFolder with a value like "a/b", "sub/dir", "parent\\child", or a URL-decoded "%2F". A client that tries to upload into a nested path via the folderName parameter.

Common situations: Migrating from an older AnythingLLM version where nested folders were tolerated; a third-party integration sending OS-style paths as the folder; a user typing "projects/2024" in the folder field.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/e5091ed9ad26d316. Report an issue: GitHub.