FlowiseAI/Flowise · error · Error

Invalid filename: filename is required and must be a string

Error message

Invalid filename: filename is required and must be a string

What it means

Thrown by validateFilename when the filename argument is falsy (null, undefined, '', 0) or not a string type. validateFilename is the entry guard for validateMimeTypeAndExtensionMatch, so this fires before any MIME/extension logic. It is a type/contract violation from the caller, not a security finding.

Source

Thrown at packages/components/src/validator.ts:103

        // eslint-disable-next-line no-control-regex
        /[\x00-\x1f]/, // Control characters
        /^\/[^/]/, // Absolute Unix paths (starting with /)
        /^[a-zA-Z]:\\/, // Absolute Windows paths (C:\)
        /^\\\\[^\\]/, // UNC paths (\\server\)
        /^\\\\\?\\/ // Extended-length paths (\\?\)
    ]

    return dangerousPatterns.some((pattern) => pattern.test(filePath))
}

/**
 * Validates filename format and security
 * @param {string} filename The filename to validate
 * @returns {void} Throws an error if validation fails
 */
const validateFilename = (filename: string): void => {
    if (!filename || typeof filename !== 'string') {
        throw new Error('Invalid filename: filename is required and must be a string')
    }
    if (isUnsafeFilePath(filename)) {
        throw new Error(`Invalid filename: unsafe characters or path traversal attempt detected in filename "${filename}"`)
    }
}

/**
 * Extracts and normalizes file extension from filename
 * @param {string} filename The filename
 * @returns {string} The normalized extension (lowercase, without dot) or empty string
 */
const extractFileExtension = (filename: string): string => {
    const filenameParts = filename.split('.')
    if (filenameParts.length <= 1) {
        return ''
    }
    let ext = filenameParts.pop()!.toLowerCase()
    // Normalize common extension variations to match MIME type mappings

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Check that req.file / the upload object exists and has a string filename before calling validateMimeTypeAndExtensionMatch.
  2. Return a 400 'no file provided' from the handler when the file is missing rather than letting validation throw.
  3. Type the caller so filename is enforced as string at compile time.

Example fix

// before
validateFilename(filename)

// after — guard at the handler boundary
if (!req.file || typeof req.file.originalname !== 'string') {
  return res.status(400).json({ error: 'A file with a valid filename is required' })
}
validateMimeTypeAndExtensionMatch(req.file.originalname, req.file.mimetype)
Defensive patterns

Strategy: type-guard

Validate before calling

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length > 0
}

Type guard

function isValidFilename(v: unknown): v is string {
  return typeof v === 'string' && v.length > 0
}

Try / catch

if (!isValidFilename(filename)) {
  throw new Error('Invalid filename: filename is required and must be a string')
}

Prevention

When it happens

Trigger: Multer/formidable provided req.file as undefined because no file was uploaded but the handler still called validate; a caller passed file.originalname which is undefined for a malformed multipart part; programmatic caller passed null filename by mistake.

Common situations: File upload handler invoked validation unconditionally even when the field is optional; client sent a multipart part without a filename; refactor changed the shape of the upload object (filename moved from .name to .originalname) and the caller wasn't updated.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/7f72b34d8296cb1a. Report an issue: GitHub.