charmbracelet/crush · critical
failed to create data directory: %q %w
Error message
failed to create data directory: %q %w
What it means
setupLocalWorkspace in internal/cmd/root.go creates the data directory (crush's state dir) with os.MkdirAll 0o700. If the OS refuses (bad path, permission denied, parent not writable, path is a file), it returns 'failed to create data directory: %q %w'. Startup aborts since crush cannot persist sessions/state.
Source
Thrown at internal/cmd/root.go:292
dataDir, _ := cmd.Flags().GetString("data-dir")
ctx := cmd.Context()
cwd, err := ResolveCwd(cmd)
if err != nil {
return nil, nil, err
}
store, err := config.Init(cwd, dataDir, debug)
if err != nil {
return nil, nil, err
}
cfg := store.Config()
store.Overrides().SkipPermissionRequests = yolo
store.Overrides().EnabledChannels = channels
if err := os.MkdirAll(cfg.Options.DataDirectory, 0o700); err != nil {
return nil, nil, fmt.Errorf("failed to create data directory: %q %w", cfg.Options.DataDirectory, err)
}
gitIgnorePath := filepath.Join(cfg.Options.DataDirectory, ".gitignore")
if _, err := os.Stat(gitIgnorePath); os.IsNotExist(err) {
if err := os.WriteFile(gitIgnorePath, []byte("*\n"), 0o644); err != nil {
return nil, nil, fmt.Errorf("failed to create .gitignore file: %q %w", gitIgnorePath, err)
}
}
if err := projects.Register(cwd, cfg.Options.DataDirectory); err != nil {
slog.Warn("Failed to register project", "error", err)
}
conn, err := db.Connect(ctx, cfg.Options.DataDirectory)
if err != nil {
return nil, nil, err
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Check the printed path: ensure no file exists there (rm/mv it if so) and its parent is writable
- Fix permissions: mkdir -p and chown/chmod the parent directory
- Set a writable data directory in crush config (options/data_directory) e.g. under $HOME
- Run outside read-only sandboxes or mount a writable volume for the data dir
Example fix
// before
cfg.Options.DataDirectory = "/var/lib/crush" // root-owned, not writable
// after
cfg.Options.DataDirectory = filepath.Join(os.Getenv("HOME"), ".local", "share", "crush") Defensive patterns
Strategy: validation
Validate before calling
dir := cfg.Options.DataDirectory
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("data directory path %s is a file", dir)
}
if err := os.MkdirAll(dir, 0o700); err != nil {
return fmt.Errorf("cannot create %s: %w", dir, err)
} Try / catch
if err := os.MkdirAll(dataDir, 0o700); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {
// fix permissions or pick another dir
}
return err
} Prevention
- Point data_directory at a user-writable path (e.g. $XDG_DATA_HOME/crush)
- Never place a file at the data directory path
- Avoid read-only containers without a writable volume for state
When it happens
Trigger: DataDirectory configured to a path whose parent is not writable; a regular file already exists at the path; read-only filesystem; restricted sandbox/containers blocking mkdir; invalid characters or empty path.
Common situations: Running crush in a read-only container or CI sandbox; HOME unset so path resolves oddly; overriding data directory in config to a root-owned location; disk full or quota exceeded.
Related errors
- failed to create data directory: %w
- failed to create .gitignore file: %q %w
- failed to create parent directories: %w
- failed to create output file: %w
- failed to access file: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/d5170763c72d0aea.
Report an issue: GitHub.