{"record":{"id":"50000310658043ea","repo":"gastownhall/beads","slug":"fs-createbeadsdir-mkdir-s-w","errorCode":null,"errorMessage":"fs: CreateBeadsDir: mkdir %s: %w","messagePattern":"fs: CreateBeadsDir: mkdir (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/fs/beads.go","lineNumber":68,"sourceCode":"func (r *beadsDirFSRepositoryImpl) BeadsDirIsLocal(ctx context.Context) bool {\n\tworkDir := filepath.Clean(utils.CanonicalizePath(r.workDir))\n\tbeadsDir := filepath.Clean(utils.CanonicalizePath(r.beadsDir))\n\tif beadsDir == workDir {\n\t\treturn true\n\t}\n\trel, err := filepath.Rel(workDir, beadsDir)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn rel != \"..\" && !strings.HasPrefix(rel, \"..\"+string(filepath.Separator))\n}\n\nfunc (r *beadsDirFSRepositoryImpl) CreateBeadsDir(ctx context.Context) error {\n\tif r.beadsDir == \"\" {\n\t\treturn fmt.Errorf(\"fs: CreateBeadsDir: beadsDir not resolved\")\n\t}\n\tif err := os.MkdirAll(r.beadsDir, config.BeadsDirPerm); err != nil {\n\t\treturn fmt.Errorf(\"fs: CreateBeadsDir: mkdir %s: %w\", r.beadsDir, err)\n\t}\n\tif _, err := config.FixBeadsDirPermissions(r.beadsDir); err != nil {\n\t\treturn fmt.Errorf(\"fs: CreateBeadsDir: fix perms %s: %w\", r.beadsDir, err)\n\t}\n\treturn nil\n}\n\nfunc (r *beadsDirFSRepositoryImpl) BeadsDirExists(ctx context.Context) (bool, error) {\n\tinfo, err := os.Stat(r.beadsDir)\n\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"fs: BeadsDirExists: stat %s: %w\", r.beadsDir, err)\n\t}\n\treturn info.IsDir(), nil\n}\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/fs/beads.go#L50-L86","documentation":"This error wraps a failure from os.MkdirAll when creating the .beads directory. It is thrown by CreateBeadsDir when the directory cannot be created at the resolved beadsDir path (permissions, parent missing in a read-only tree, path is a file, etc.). The wrapped OS error (%w) carries the underlying cause.","triggerScenarios":"Calling CreateBeadsDir (e.g. via bd init) when os.MkdirAll(r.beadsDir, config.BeadsDirPerm) fails: parent directory does not exist and cannot be created, permission denied, path component is a regular file, disk full, or read-only filesystem.","commonSituations":"Running bd inside a read-only mount or container filesystem; beadsDir points under a path owned by another user; a stale file named .beads exists where the directory should be; umask/capability restrictions in CI sandboxes.","solutions":["Check the wrapped %w cause in the error message (e.g. 'permission denied', 'not a directory') and fix the filesystem condition directly","Verify the parent path of beadsDir exists and is writable: ls -ld $(dirname <beadsDir>) and mkdir -p it manually if needed","If a regular file exists at beadsDir, remove or rename it so the directory can be created","Ensure the process user has write permission on the target location, or run from a writable working directory"],"exampleFix":"// before\nrepo := fsrepo.New(fsrepo.WithBeadsDir(\"/proc/self/beads\"))\nrepo.CreateBeadsDir(ctx) // mkdir /proc/self/beads: permission denied\n// after\nbeadsDir := filepath.Join(os.Getenv(\"HOME\"), \"project\", \".beads\")\nos.MkdirAll(filepath.Dir(beadsDir), 0o755) // ensure writable parent\nrepo.CreateBeadsDir(ctx)","handlingStrategy":"validation","validationCode":"func canCreateDir(path string) error {\n\tfi, err := os.Stat(path)\n\tif err == nil && !fi.IsDir() {\n\t\treturn fmt.Errorf(\"%s is a file, not a directory\", path)\n\t}\n\tfor dir := filepath.Dir(path); ; dir = filepath.Dir(dir) {\n\t\tif err := unix.Access(dir, unix.W_OK|unix.X_OK); err != nil {\n\t\t\treturn fmt.Errorf(\"%s not writable: %v\", dir, err)\n\t\t}\n\t\tif dir == filepath.Dir(dir) { return nil }\n\t}\n}\nif err := canCreateDir(beadsDir); err != nil { return err }\nrepo.CreateBeadsDir(ctx)","typeGuard":"func isMkdirErr(err error) bool {\n\tvar pe *fs.PathError\n\treturn errors.As(err, &pe) && pe.Op == \"mkdir\"\n}","tryCatchPattern":"if err := repo.CreateBeadsDir(ctx); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {\n\t\treturn fmt.Errorf(\"cannot create %s: check ownership/permissions of parent dirs\", pe.Path)\n\t}\n\treturn err\n}","preventionTips":["Run bd from a directory writable by the current user, not system or root-owned paths","Never pre-create .beads as root or with sudo in shared environments","Check for stray files named .beads before initializing","In containers, mount the workspace volume read-write"],"tags":["filesystem","mkdir","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}