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

  1. Pass a concrete non-empty file path such as '/windows/win.ini'
  2. If the path comes from a variable, verify the extractor/population step produced a value before calling ReadFile
  3. 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

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


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/80901040d2837383. Report an issue: GitHub.