Mintplex-Labs/anything-llm · error · Error

Invalid path.

Error message

Invalid path.

What it means

Thrown by normalizePath() after it strips leading `../` segments and trims. It is a path-traversal / degenerate-path guard: if the cleaned result is exactly "..", ".", or "/", the caller supplied an input that resolves to nothing safe, so the function refuses to return a usable path. Anything that flows user-controlled strings (folder names, filenames, doc locations) through normalizePath can surface this.

Source

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

 * @returns {boolean} True if `inner` is strictly inside `outer`, false otherwise.
 */
function isWithin(outer, inner) {
  const resolvedOuter = path.resolve(outer);
  const resolvedInner = path.resolve(inner);
  const rel = path.relative(resolvedOuter, resolvedInner);

  if (rel === "") return false;
  return (
    !rel.startsWith(`..${path.sep}`) && rel !== ".." && !path.isAbsolute(rel)
  );
}

function normalizePath(filepath = "") {
  const result = path
    .normalize(filepath.trim())
    .replace(/^(\.\.(\/|\\|$))+/, "")
    .trim();
  if (["..", ".", "/"].includes(result)) throw new Error("Invalid path.");
  return result;
}

/**
 * Strips characters that are illegal in Windows filenames, including Unicode
 * quotation marks (U+201C, U+201D, etc.) that can get corrupted into ASCII
 * double-quotes during charset conversion in the upload pipeline.
 * @param {string} fileName - The filename to sanitize.
 * @returns {string} - The sanitized filename.
 */
function sanitizeFileName(fileName) {
  if (!fileName) return fileName;
  return fileName.replace(
    /[<>:"/\\|?*\u201C\u201D\u201E\u201F\u2018\u2019\u201A\u201B]/g,
    ""
  );
}

View on GitHub (pinned to 526360e320)

Solutions

  1. Validate the input before calling normalizePath: reject empty, whitespace-only, and pure-dot/separator strings.
  2. Treat the thrown Error as a 400 Bad Request at the endpoint boundary and surface a user-facing message rather than a stack trace.
  3. If a default is acceptable for your caller, fall back to a generated safe name (e.g. uuid) instead of passing degenerate input.
  4. Audit every call site that forwards req.params or req.body filenames into normalizePath to ensure they are single-segment names.

Example fix

// before
const folder = normalizePath(folderName); // throws on "..", ".", "/"

// after
if (!folderName || /^[./\\]+$/.test(folderName))
  return response.status(400).json({ error: "A real folder name is required." });
const folder = normalizePath(folderName);
Defensive patterns

Strategy: validation

Validate before calling

function isSafePathSegment(name = '') {
  const trimmed = String(name).trim();
  if (!trimmed) return false;
  if (['..', '.', '/'].includes(trimmed)) return false;
  if (/^[./\\]+$/.test(trimmed)) return false;
  if (trimmed.includes('/') || trimmed.includes('\\')) return false;
  return true;
}
// call before normalizePath
if (!isSafePathSegment(folderName)) return res.status(400).json({ error: 'Invalid path.' });

Type guard

function isNonDegeneratePathName(v): v is string {
  return typeof v === 'string' && v.trim().length > 0 && !['..','.','/'].includes(v.trim()) && !/^[./\\]+$/.test(v);
}

Try / catch

try {
  const p = normalizePath(input);
} catch (e) {
  if (e.message === 'Invalid path.') return res.status(400).json({ error: e.message });
  throw e;
}

Prevention

When it happens

Trigger: Calling normalizePath with the literal strings "..", ".", or "/"; with values that are only separators like "//" or "\\\\"; or with traversal payloads like "../../../.." whose leading-dotdir strip leaves nothing. Any /v1/document/upload/:folderName, logo rename, or doc-move path that hands a raw user string here.

Common situations: A frontend sending an empty-or-dots folder name on document upload; a migration script passing filesystem roots; a test fixture using "." as a placeholder; URL-encoded traversal (`%2e%2e`) decoded upstream before this call.

Related errors


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