Mintplex-Labs/anything-llm · error

Invalid path.

Error message

Invalid path.

What it means

Thrown by `normalizePath` after it strips leading `..` segments and the remainder collapses to exactly `..`, `.`, or `/`. This is a path-traversal / root-escape guard: those three results would resolve outside or to the root of the intended directory tree, so the function refuses to return them. It complements the leading-`..` regex strip with a final shape check.

Source

Thrown at collector/utils/files/index.js:224

 * @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. Treat this error as a security signal — investigate the source of the path input rather than silencing it.
  2. Ensure upstream `sanitizeFileName` runs first so filenames never reach normalizePath as pure traversal strings.
  3. Reject user-supplied `destinationOverride` values that are absolute or contain `..` before calling normalizePath.
  4. If legitimately constructing a path, build it from trusted components via `path.join(knownRoot, safeRelative)` instead of normalizing user input.
  5. Add a test asserting traversal inputs throw.

Example fix

// before
const safe = normalizePath(userInput); // may throw 'Invalid path.'

// after — reject traversal at the boundary, then normalize
if (typeof userInput !== 'string' || /[\/]|^(?:\.\.?)+$/.test(userInput.trim())) {
  throw new Error('Destination must be a relative path without traversal segments');
}
const safe = normalizePath(userInput);
Defensive patterns

Strategy: validation

Validate before calling

function isSafeRelativePath(p) {
  if (typeof p !== 'string') return false;
  const s = p.trim();
  if (s === '' || s === '.' || s === '..' || path.isAbsolute(s)) return false;
  if (/(^|\\)\.\.?(\\|$)/.test(s)) return false; // any traversal segment
  return true;
}
// only call normalizePath when isSafeRelativePath is true

Type guard

function isNormalizedSafe(result) {
  return typeof result === 'string' && result !== '..' && result !== '.' && result !== '/';
}

Try / catch

try {
  const safe = normalizePath(input);
} catch (e) {
  if (/Invalid path/i.test(e.message)) {
    // SECURITY: treat as malicious/malformed — reject the request, do not fall back
    throw new Error('Rejected: path traversal is not allowed');
  }
  throw e;
}

Prevention

When it happens

Trigger: Input like `../../../..` that normalizes to `..`; input of `..` or `.` directly; an absolute path `/` that survives normalization; a filename or override path composed entirely of traversal segments; crafted/malicious `destinationOverride` or uploaded filename attempting to escape the documents folder.

Common situations: User-controlled filenames or paths (uploads, destination overrides) containing traversal sequences; a sanitizer upstream strips everything except dots; security testing/probing of the upload endpoint.

Related errors


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