{"record":{"id":"ddb2efc485d9a5ac","repo":"gastownhall/beads","slug":"failed-to-create-backup-dir-in-git-repo-w","errorCode":null,"errorMessage":"failed to create backup dir in git-repo: %w","messagePattern":"failed to create backup dir in git-repo: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/backup_export.go","lineNumber":40,"sourceCode":"}\n\n// backupDir returns the backup directory path, creating it if needed.\n// When backup.git-repo is set to a valid git repo, returns a backup/ subdirectory\n// inside that repo. Otherwise it requires an active beads workspace and uses its\n// backup/ subdirectory.\nfunc backupDir() (string, error) {\n\tgitRepo := config.GetString(\"backup.git-repo\")\n\tif gitRepo != \"\" {\n\t\tif strings.HasPrefix(gitRepo, \"~/\") {\n\t\t\thome, _ := os.UserHomeDir()\n\t\t\tgitRepo = filepath.Join(home, gitRepo[2:])\n\t\t}\n\t\tif _, err := os.Stat(filepath.Join(gitRepo, \".git\")); err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"Warning: backup.git-repo %s is not a git repo, falling back to .beads/backup\\n\", gitRepo)\n\t\t} else {\n\t\t\tdir := filepath.Join(gitRepo, \"backup\")\n\t\t\tif err := os.MkdirAll(dir, 0700); err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to create backup dir in git-repo: %w\", err)\n\t\t\t}\n\t\t\treturn dir, nil\n\t\t}\n\t}\n\tbeadsDir := beads.FindBeadsDir()\n\tif beadsDir == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%s; %s\", activeWorkspaceNotFoundError(), diagHint())\n\t}\n\tdir := filepath.Join(beadsDir, \"backup\")\n\tif err := os.MkdirAll(dir, 0700); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create backup directory: %w\", err)\n\t}\n\treturn dir, nil\n}\n\n// loadBackupState reads the backup state file, returning a zero state if missing.\nfunc loadBackupState(dir string) (*backupState, error) {\n\tpath := filepath.Join(dir, \"backup_state.json\")","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/backup_export.go#L22-L58","documentation":"backupDir determines the local backup directory. When backup.git-repo is configured and points at a valid git repo, it creates <gitRepo>/backup with 0700 permissions; if os.MkdirAll fails (permissions, read-only filesystem, path conflicts), it wraps the OS error as 'failed to create backup dir in git-repo: %w'. The wrapped cause names the exact filesystem problem.","triggerScenarios":"Running backup export (runBackupExport) or auto-backup (maybeAutoBackup) with backup.git-repo set, where creating <gitRepo>/backup fails: parent dir not writable, gitRepo path on a read-only mount, or a file named 'backup' already exists at that path.","commonSituations":"git-repo on a read-only CI volume, permission-restricted shared server, SELinux/AppArmor restrictions, or a stale regular file blocking the 'backup' directory path.","solutions":["Check permissions on the git-repo parent directory and ensure the process user can create directories there","Remove or rename any non-directory file at <gitRepo>/backup that blocks MkdirAll","Unset backup.git-repo to fall back to .beads/backup inside the writable workspace","Check the wrapped OS error (permission denied vs read-only) and fix the mount or ACL accordingly"],"exampleFix":"// before\n# backup.git-repo = /mnt/readonly/repo\nbd backup export\n// error: failed to create backup dir in git-repo: mkdir /mnt/readonly/repo/backup: read-only file system\n// after: point git-repo at a writable location or drop the setting\nbd config set backup.git-repo /home/user/repo  # or unset it","handlingStrategy":"validation","validationCode":"gitRepo := cfg.BackupGitRepo\nif st, err := os.Stat(filepath.Join(gitRepo, \".git\")); err == nil && st.IsDir() {\n    if f, err := os.OpenFile(gitRepo, os.O_WRONLY, 0700); err != nil {\n        return fmt.Errorf(\"git-repo %s not writable: %w\", gitRepo, err)\n    } else { f.Close() }\n}","typeGuard":null,"tryCatchPattern":"dir, err := backupDir()\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create backup dir in git-repo\") {\n        // fall back to default .beads/backup or abort with a clear message\n    }\n    return err\n}","preventionTips":["Point backup.git-repo at a writable, real git repository (contains .git)","Pre-create and permission the <gitRepo>/backup directory in provisioning","Watch for the stderr warning about invalid git-repo and fix config promptly"],"tags":["go","filesystem","backup"],"backgroundTag":"mkdir-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}