projectdiscovery/nuclei · error
file path cannot be empty
Error message
file path cannot be empty
What it means
Thrown by readFile in the smbsession library when the normalized file path is "." — i.e. the path argument resolves to the share root instead of a file. NormalizeSharePath collapses empty strings, ".", and "./" to ".", and reading the root itself is not a file read, so the library rejects it explicitly before touching the network.
Source
Thrown at pkg/js/libs/smbsession/session.go:222
}
out = append(out, fileInfoToEntry(fi))
}
return out, nil
}
func readFile(ops shareBackend, share, filePath string, maxBytes int64) (string, error) {
if err := RequireShareName(share); err != nil {
return "", err
}
if maxBytes <= 0 {
maxBytes = DefaultMaxReadBytes
}
normalized, err := NormalizeSharePath(filePath)
if err != nil {
return "", err
}
if normalized == "." {
return "", fmt.Errorf("file path cannot be empty")
}
if err := ops.UseShare(share); err != nil {
return "", fmt.Errorf("mount share %q: %w", share, err)
}
// Prefer streaming Open+LimitReader when the backend supports it (tests /
// future goimpacket Open). Fall back to Cat for the stock client.
if opener, ok := ops.(shareOpener); ok {
f, err := opener.Open(normalized)
if err != nil {
return "", err
}
defer func() { _ = f.Close() }()
limited := io.LimitReader(f, maxBytes+1)
body, err := io.ReadAll(limited)
if err != nil {
return "", err
}
if int64(len(body)) > maxBytes {View on GitHub (pinned to 265b3a3dec)
Solutions
- Pass a concrete non-empty file path such as '/windows/win.ini'
- If the path comes from a variable, verify the extractor/population step produced a value before calling ReadFile
- Use ListTree/ListDir to list a directory instead of ReadFile
Example fix
// before
const data = client.ReadFile('C$', path, 0); // path is ''
// after
if (path && path !== '.' && path !== './') {
const data = client.ReadFile('C$', path, 0);
} Defensive patterns
Strategy: validation
Validate before calling
function isRealFilePath(p) { return typeof p === 'string' && p.trim() !== '' && p !== '.' && p !== './'; }
if (isRealFilePath(filePath)) { client.ReadFile(share, filePath, 0); } Type guard
function isRealFilePath(p) { return typeof p === 'string' && p.trim() !== '' && p.trim() !== '.'; } Try / catch
try { client.ReadFile(share, p, 0) } catch (e) { if (String(e).includes('file path cannot be empty')) { /* skip empty target */ } else { throw e; } } Prevention
- Guard paths sourced from extractors before reading
- Default to a concrete well-known file path
- Use ListTree for directories, never ReadFile
When it happens
Trigger: Calling ReadFile(share, '') or ReadFile(share, '.'); building the path from a variable that is empty due to a failed extract or missing variable interpolation; passing './' expecting the root directory listing.
Common situations: Templates that read a path extracted from a previous step where the extractor matched nothing; default parameter values left as empty strings; confusion between ReadFile and ListTree for directory content.
Related errors
- mount share %q: %w
- file %q exceeds max read size of %d bytes
- tree listing exceeded max entries (%d)
- invalid number of recipients: required 1, got %d
- invalid host or port
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/80901040d2837383.
Report an issue: GitHub.