danny-avila/LibreChat · error

Invalid file path: ${cleanFilepath}

Error message

Invalid file path: ${cleanFilepath}

What it means

Thrown by deleteLocalFile when the cleaned filepath starts with /uploads/{userId} but has no path component after the user-specific prefix — meaning the filepath is exactly /uploads/{userId} or /uploads/{userId}/ with nothing following. The split produces an empty basePath, indicating a malformed or incomplete file path that cannot map to an actual file on disk.

Source

Thrown at api/server/services/Files/Local/crud.js:244

 * @returns {Promise<void>}
 *          A promise that resolves when the file has been successfully deleted, or throws an error if the
 *          file path is invalid or if there is an error in deletion.
 */
const deleteLocalFile = async (req, file) => {
  const appConfig = req.config;
  const { publicPath, uploads } = appConfig.paths;

  /** Filepath stripped of query parameters (e.g., ?manual=true) */
  const cleanFilepath = file.filepath.split('?')[0];

  await deleteRagFile({ userId: req.user.id, file });

  if (cleanFilepath.startsWith(`/uploads/${req.user.id}`)) {
    const userUploadDir = path.join(uploads, req.user.id);
    const basePath = cleanFilepath.split(`/uploads/${req.user.id}/`)[1];

    if (!basePath) {
      throw new Error(`Invalid file path: ${cleanFilepath}`);
    }

    const filepath = path.join(userUploadDir, basePath);

    const rel = path.relative(userUploadDir, filepath);
    if (rel.startsWith('..') || path.isAbsolute(rel) || rel.includes(`..${path.sep}`)) {
      throw new Error(`Invalid file path: ${cleanFilepath}`);
    }

    await unlinkFile(filepath);
    return;
  }

  const parts = cleanFilepath.split(path.sep);
  const subfolder = parts[1];
  if (!subfolder && parts[0] === EModelEndpoint.agents) {
    logger.warn(`Agent File ${file.file_id} is missing filepath, may have been deleted already`);
    return;

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Inspect the file record in the database and verify file.filepath is a complete path like /uploads/{userId}/{file_id}__{filename}.
  2. If the record is stale or corrupted, remove it from the database directly rather than attempting file deletion.
  3. Audit the upload pipeline (uploadLocalFile) to ensure filepath is always fully constructed before being persisted.
  4. Handle this error at the controller level and return a 404 or 422 with a message indicating the file path is invalid.
Defensive patterns

Strategy: validation

Validate before calling

const cleanFilepath = file.filepath.split('?')[0];
if (cleanFilepath.startsWith(`/uploads/${req.user.id}`)) {
  const basePath = cleanFilepath.split(`/uploads/${req.user.id}/`)[1];
  if (!basePath) {
    throw new Error('File record has incomplete path — no filename component');
  }
}

Type guard

function hasCompleteUploadPath(filepath: string, userId: string): boolean {
  const clean = filepath.split('?')[0];
  const parts = clean.split(`/uploads/${userId}/`);
  return parts.length === 2 && parts[1].length > 0;
}

Try / catch

try {
  await deleteLocalFile(req, file);
} catch (error) {
  if (error.message.startsWith('Invalid file path')) {
    // data integrity issue — log and skip
    logger.warn(`Skipping deletion of malformed file record ${file.file_id}`);
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling deleteLocalFile(req, file) where file.filepath (after stripping query params) equals /uploads/{userId} or /uploads/{userId}/ — i.e., it references the user's upload directory root rather than a specific file within it.

Common situations: A database record has a truncated or corrupted filepath field that was accidentally set to the directory prefix. Or a file was partially created and the filepath was stored before the filename was appended. This is typically a data-integrity issue rather than a user-actionable condition.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/eb938161692d27b7. Report an issue: GitHub.