{"record":{"id":"b00d4831c4389fec","repo":"gastownhall/beads","slug":"cannot-create-shared-server-directory-s-w","errorCode":null,"errorMessage":"cannot create shared server directory %s: %w","messagePattern":"cannot create shared server directory (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/doltserver.go","lineNumber":268,"sourceCode":"\t\treturn d, nil\n\t}\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot determine home directory: %w\", err)\n\t}\n\treturn filepath.Join(home, \".beads\", \"shared-server\"), nil\n}\n\n// SharedServerDir returns the directory for shared server state files.\n// Returns ~/.beads/shared-server/ (created on first use).\n// Override with BEADS_SHARED_SERVER_DIR env var for testing or custom layouts.\nfunc SharedServerDir() (string, error) {\n\tdir, err := SharedServerPath()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := os.MkdirAll(dir, config.BeadsDirPerm); err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot create shared server directory %s: %w\", dir, err)\n\t}\n\treturn dir, nil\n}\n\n// SharedDoltDir returns the dolt data directory for the shared server.\n// Returns ~/.beads/shared-server/dolt/ (created on first use).\nfunc SharedDoltDir() (string, error) {\n\tserverDir, err := SharedServerDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdir := filepath.Join(serverDir, \"dolt\")\n\tif err := os.MkdirAll(dir, config.BeadsDirPerm); err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot create shared dolt directory %s: %w\", dir, err)\n\t}\n\treturn dir, nil\n}\n","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/doltserver.go#L250-L286","documentation":"SharedServerDir lazily creates the shared dolt server directory (typically ~/.beads/shared-server/) used in shared-server mode. It wraps os.MkdirAll with config.BeadsDirPerm; if the OS refuses to create the directory, the path and underlying OS error are wrapped into this error. It is thrown by the library because the shared server cannot start without its state directory on disk.","triggerScenarios":"Calling SharedServerDir() (directly or via SharedDoltDir/resolveServerDir/DefaultConfig) when os.MkdirAll on the shared server path fails — e.g. HOME is unset or unwritable, ~/.beads is owned by another user, a file exists at the directory path, or the disk is full/readonly.","commonSituations":"Running bd under a service account with no writable HOME, HOME pointing to a read-only NFS mount, a stray file named shared-server inside ~/.beads, or container images with a read-only root filesystem and no volume for ~/.beads.","solutions":["Check the wrapped OS error in the message for the root cause (EACCES, ENOSPC, ENOTDIR, etc.)","Verify $HOME is set and writable: touch $HOME/.beads/test","If a plain file exists at ~/.beads/shared-server, remove or rename it","Fix permissions: chown/chmod the ~/.beads tree, or mount a writable volume","Free disk space or remount the filesystem read-write"],"exampleFix":"// before: blindly calling and panicking on error\ndir, _ := doltserver.SharedServerDir()\n// after: handle the wrapped OS error\ndir, err := doltserver.SharedServerDir()\nif err != nil {\n    return fmt.Errorf(\"shared server unavailable: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check before calling SharedServerDir\nhome := os.Getenv(\"HOME\")\nif home == \"\" {\n    return fmt.Errorf(\"HOME is not set; cannot locate shared server dir\")\n}\nif fi, err := os.Stat(filepath.Join(home, \".beads\")); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"~/.beads is a file, not a directory\")\n}","typeGuard":"func isSharedDirErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"cannot create shared server directory\")\n}","tryCatchPattern":"dir, err := doltserver.SharedServerDir()\nif err != nil {\n    if strings.Contains(err.Error(), \"permission denied\") {\n        // fall back to a writable BEADS_DIR or abort with guidance\n    }\n    return err\n}","preventionTips":["Ensure $HOME is set and writable for the user running bd","Never run bd under sudo; fix ownership of ~/.beads if you did","Keep a writable volume mounted at ~/.beads in containers","Don't create files where bd expects directories under ~/.beads"],"tags":["filesystem","mkdir","permissions","shared-server"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}