moonD4rk/HackBrowserData · error
--data-dir %q has no per-browser subdir but keys has %d brow
Error message
--data-dir %q has no per-browser subdir but keys has %d browsers; point it at the archive root, or use -b <browser> for one browser's User Data (have: %s)
What it means
BuildFromDump's layout probe (isArchiveLayout) determined the data dir has no per-browser subdirectories, yet the filtered keys dump carries more than one browser vault, so there is no unambiguous way to bind each key set to a profile directory. This is an ambiguity guard: single-vault data dirs are fine raw, but multi-vault requires the conventional archive layout (e.g. a User Data root with per-browser subdirs) or an explicit -b filter to narrow to exactly one browser.
Source
Thrown at browser/keydump.go:91
var selected []masterkey.Vault
for _, v := range dump.Vaults {
if filter != "" && !strings.EqualFold(v.Browser, filter) {
continue
}
selected = append(selected, v)
}
if filter != "" && len(selected) == 0 {
return nil, fmt.Errorf("no vault for browser %q in keys (have: %s)", filter, vaultKeys(dump))
}
if !dirExists(dataDir) {
return nil, fmt.Errorf("data dir %q does not exist", dataDir)
}
archiveLayout := isArchiveLayout(dataDir, selected)
if !archiveLayout && len(selected) > 1 {
return nil, fmt.Errorf("--data-dir %q has no per-browser subdir but keys has %d browsers; "+
"point it at the archive root, or use -b <browser> for one browser's User Data (have: %s)",
dataDir, len(selected), vaultKeys(dump))
}
var browsers []Browser
for _, v := range selected {
root := dataDir
if archiveLayout {
root = filepath.Join(dataDir, strings.ToLower(v.Browser))
if !dirExists(root) {
log.Warnf("restore: %s has no data under %s, skipping", v.Browser, root)
continue
}
}
kind, err := kindFromDump(v.Kind)
if err != nil {
log.Warnf("restore: %s: %v", v.Browser, err)
continueView on GitHub (pinned to 0503d04d7a)
Solutions
- Add -b <browser> to select the single browser whose User Data the dir directly contains
- Repoint --data-dir at the archive root that contains one subdirectory per browser so vaults can be matched by subdirectory
- Restructure the copied tree into per-browser subdirectories matching the browsers listed in the keys dump
- Regenerate the keys dump with only one browser if the others are irrelevant
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at browser/keydump.go:91 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/f33b17202158ea9f.
Report an issue: GitHub.