{"record":{"id":"9b945e1aca812e3a","repo":"gastownhall/beads","slug":"backup-destination-is-not-a-directory-s","errorCode":null,"errorMessage":"backup destination is not a directory: %s","messagePattern":"backup destination is not a directory: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":1297,"sourceCode":"\t}\n\tdefer db.Close()\n\treturn versioncontrolops.BackupSync(ctx, db, name)\n}\n\n// BackupRemove removes a configured Dolt backup destination.\nfunc (s *DoltStore) BackupRemove(ctx context.Context, name string) error {\n\treturn versioncontrolops.BackupRemove(ctx, s.db, name)\n}\n\n// BackupDatabase registers dir as a file:// Dolt backup remote and syncs\n// the full database to it, preserving complete commit history.\nfunc (s *DoltStore) BackupDatabase(ctx context.Context, dir string) error {\n\tinfo, err := os.Stat(dir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"backup destination does not exist: %w\", err)\n\t}\n\tif !info.IsDir() {\n\t\treturn fmt.Errorf(\"backup destination is not a directory: %s\", dir)\n\t}\n\n\tbackupURL, err := versioncontrolops.DirToFileURL(dir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbackupName := \"backup_export\"\n\n\tsyncDB, err := s.oneShotConn(0)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer syncDB.Close()\n\n\t// Register as a backup remote (idempotent — remove first if exists).\n\t_ = versioncontrolops.BackupRemove(ctx, s.db, backupName)\n\tif err := versioncontrolops.BackupAdd(ctx, s.db, backupName, backupURL); err != nil {\n\t\t// Another backup (e.g. \"default\" registered by `bd backup init`) may","sourceCodeStart":1279,"sourceCodeEnd":1315,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L1279-L1315","documentation":"BackupDatabase validated its destination with os.Stat and found the path exists but is not a directory (e.g. it is a regular file, symlink to a file, or device). A file:// Dolt backup remote requires a directory target, so the backup is refused before any sync. Note this message embeds the path, not a wrapped cause.","triggerScenarios":"Calling DoltStore.BackupDatabase(ctx, dir) where dir exists but info.IsDir() is false — a plain file occupies the path, or the path is a socket/device node.","commonSituations":"A previous single-file backup or tarball sits at the path the user now wants to use as a backup directory; a script wrote a marker file to the intended backup location; tab-completion picked a similarly named file.","solutions":["Move or remove the file at that path (rm/mv), then create a directory: mkdir -p <dir>.","Choose a different destination directory that is empty or dedicated to backups.","If the path is a symlink, confirm it resolves to a directory; if it resolves to a file, fix the link target.","Check your script/config for a variable that accidentally holds a filename instead of a directory path."],"exampleFix":"// before: path holds an old backup.tar\nstore.BackupDatabase(ctx, \"/backups/beads\") // not a directory\n// after\nos.Rename(\"/backups/beads\", \"/backups/beads.tar.bak\")\nos.MkdirAll(\"/backups/beads\", 0o755)\nstore.BackupDatabase(ctx, \"/backups/beads\")","handlingStrategy":"validation","validationCode":"info, err := os.Stat(dir)\nif err == nil && !info.IsDir() {\n    return fmt.Errorf(\"%s exists but is not a directory; choose another path\", dir)\n}","typeGuard":"func isExistingDir(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.IsDir()\n}","tryCatchPattern":"if err := store.BackupDatabase(ctx, dir); err != nil {\n    if strings.Contains(err.Error(), \"is not a directory\") {\n        os.Rename(dir, dir+\".file.bak\")\n        os.MkdirAll(dir, 0o755)\n        err = store.BackupDatabase(ctx, dir)\n    }\n}","preventionTips":["Dedicate a directory (not a file path) as the backup target; never point backups at a tarball.","Check targets with `test -d <path>` in shell scripts before calling backup commands.","Resolve symlinks before passing a path as the backup destination."],"tags":["backup","filesystem","dolt","validation"],"backgroundTag":"path-not-a-directory","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}