moonD4rk/HackBrowserData · error

file is empty

Error message

file is empty

What it means

readFileContent queried the duplicated handle's size with GetFileSizeEx, got 0 bytes, and returned this guard error before attempting any mapping or read. It means the locked file is genuinely empty on disk (e.g. a freshly created but not-yet-flushed database, or all data still in the writer's WAL), so there is nothing to copy via this path.

Solutions

  1. Skip the copy and treat the source as having no data yet
  2. Retry after the owning process flushes/checkpoints its writes
  3. Read the companion -wal file instead if the data lives there
  4. Confirm the duplicated handle refers to the intended file, not a truncated placeholder
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at filemanager/copy_windows.go:117 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06). Data as JSON: /api/errors/6cd9022162617ea8. Report an issue: GitHub.

Appendix: source

Thrown at filemanager/copy_windows.go:117

		}
		_ = windows.CloseHandle(dupHandle)
	}

	return 0, fmt.Errorf("no process has file open: %s", targetPath)
}

// readFileContent reads file content from a duplicated handle.
// It uses FileMapping first (CreateFileMapping + MapViewOfFile), which reads
// from the OS kernel's file cache — this includes WAL data that Chrome has
// written but not yet checkpointed to the main file. Falls back to ReadFile
// if FileMapping fails.
func readFileContent(handle windows.Handle) ([]byte, error) {
	fileSize, err := winapi.GetFileSizeEx(handle)
	if err != nil {
		return nil, err
	}
	if fileSize == 0 {
		return nil, fmt.Errorf("file is empty")
	}

	size := int(fileSize)

	// Try FileMapping first — reads from kernel file cache, includes WAL data
	if data, err := winapi.MapFile(handle, size); err == nil {
		return data, nil
	}

	// FileMapping failed, fall back to ReadFile.
	// Seek to beginning first — the handle's file pointer may be at an
	// arbitrary position.
	if _, err := windows.Seek(handle, 0, 0); err != nil {
		return nil, fmt.Errorf("seek to start: %w", err)
	}
	data := make([]byte, size)
	var bytesRead uint32
	if err := windows.ReadFile(handle, data, &bytesRead, nil); err != nil {

View on GitHub (pinned to 0503d04d7a)