{"record":{"id":"8fb24e7d743b1dfb","repo":"gastownhall/beads","slug":"failed-to-create-beads-directory-w","errorCode":null,"errorMessage":"failed to create .beads directory: %w","messagePattern":"failed to create \\.beads directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/init.go","lineNumber":2370,"sourceCode":"\t{name: \"pg-schema\", usage: \"Legacy PostgreSQL schema (removed backend compatibility only)\", origin: \"the removed PostgreSQL/MySQL initialization paths\", rationale: configfile.RemovedBackendRationale},\n\t{name: \"mysql-url\", usage: \"Legacy MySQL connection URL (removed backend compatibility only)\", origin: \"the removed PostgreSQL/MySQL initialization paths\", rationale: configfile.RemovedBackendRationale},\n\t{name: \"mysql-database\", usage: \"Legacy MySQL database (removed backend compatibility only)\", origin: \"the removed PostgreSQL/MySQL initialization paths\", rationale: configfile.RemovedBackendRationale},\n\t{name: \"sqlite-path\", usage: \"Legacy SQLite database file (removed backend compatibility only)\", origin: \"the removed SQLite initialization path\", rationale: configfile.RemovedSQLiteRationale},\n}\n\n// migrateOldDatabases detects and migrates old database files to beads.db\nfunc migrateOldDatabases(targetPath string, quiet bool) error {\n\ttargetDir := filepath.Dir(targetPath)\n\ttargetName := filepath.Base(targetPath)\n\n\t// If target already exists, no migration needed\n\tif _, err := os.Stat(targetPath); err == nil {\n\t\treturn nil\n\t}\n\n\t// Create .beads directory if it doesn't exist\n\tif err := os.MkdirAll(targetDir, 0750); err != nil {\n\t\treturn fmt.Errorf(\"failed to create .beads directory: %w\", err)\n\t}\n\n\t// Look for existing .db files in the .beads directory\n\tpattern := filepath.Join(targetDir, \"*.db\")\n\tmatches, err := filepath.Glob(pattern)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to search for existing databases: %w\", err)\n\t}\n\n\t// Filter out the target file name and any backup files\n\tvar oldDBs []string\n\tfor _, match := range matches {\n\t\tbaseName := filepath.Base(match)\n\t\tif baseName != targetName && !strings.HasSuffix(baseName, \".backup.db\") {\n\t\t\toldDBs = append(oldDBs, match)\n\t\t}\n\t}\n","sourceCodeStart":2352,"sourceCodeEnd":2388,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/init.go#L2352-L2388","documentation":"During `bd init`, migrateOldDatabases creates the .beads directory (mode 0750) before scanning for legacy *.db files to rename to beads.db. This error wraps the underlying os.MkdirAll failure, meaning the directory could not be created on disk. bd throws it because without .beads there is nowhere to place or discover the database, so initialization cannot proceed.","triggerScenarios":"Running `bd init` (or a path that calls migrateOldDatabases) when os.MkdirAll(targetDir, 0750) fails — e.g. the parent directory does not exist and cannot be created, the filesystem is read-only, or a non-directory file already exists at the .beads path.","commonSituations":"Mounting the repo on a read-only volume or read-only container layer; a stale regular file named .beads blocking creation; running bd as a user without write permission on the repository root; BEADS_DIR pointing at an unwritable path; disk full.","solutions":["Check that the .beads path (or BEADS_DIR target) is not occupied by a non-directory file and remove/rename it.","Verify write permissions on the repository root (or the BEADS_DIR parent) for the current user; chown/chmod as needed.","If on a read-only mount or container layer, remount read-write or run bd from a writable location.","Check disk space (df -h) and free space if the volume is full."],"exampleFix":"// before: running in a read-only checkout\n$ bd init\n# failed to create .beads directory: mkdir .beads: read-only file system\n\n// after: run from a writable workspace or remount\n$ mount -o remount,rw /path/to/repo\n$ bd init","handlingStrategy":"try-catch","validationCode":"const st, err = os.Stat(beadsDir)\n// In Go (caller preflight):\nif fi, err := os.Stat(filepath.Dir(targetPath)); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", filepath.Dir(targetPath))\n}\nif err := unix.Access(repoRoot, unix.W_OK); err != nil {\n    return fmt.Errorf(\"repo root not writable: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := migrateOldDatabases(targetPath, quiet); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.EACCES) || errors.Is(pe.Err, syscall.EROFS)) {\n        // surface a permissions/read-only hint before retrying\n    }\n    return err\n}","preventionTips":["Ensure the repository root (and BEADS_DIR target) is writable by the user running bd before init.","Do not create a regular file named .beads; it blocks directory creation.","Avoid running init on read-only mounts or in containers with read-only layers.","Monitor disk space in CI environments that run bd init."],"tags":["filesystem","permissions","init","go"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}