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
- Validate the input before calling normalizePath: reject empty, whitespace-only, and pure-dot/separator strings.
- Treat the thrown Error as a 400 Bad Request at the endpoint boundary and surface a user-facing message rather than a stack trace.
- If a default is acceptable for your caller, fall back to a generated safe name (e.g. uuid) instead of passing degenerate input.
- 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
- Never pass raw req.params/req.body strings to normalizePath; sanitize first.
- Maintain an allow-list charset regex for folder/file names at the controller.
- Unit-test normalizePath with traversal, dot-only, and separator-only inputs.
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.