charmbracelet/crush · error
directory does not exist: %w
Error message
directory does not exist: %w
What it means
Shell.SetWorkingDir in internal/shell/shell.go verifies the target directory with os.Stat before switching the shell's working directory. If Stat fails (missing path, permission problem, or path is a file), the raw error is wrapped as "directory does not exist: %w" and the cwd is left unchanged. The shell state is protected under a mutex, so the error is atomic.
Source
Thrown at internal/shell/shell.go:148
return s.execStream(ctx, command, stdout, stderr)
}
// GetWorkingDir returns the current working directory
func (s *Shell) GetWorkingDir() string {
s.mu.Lock()
defer s.mu.Unlock()
return s.cwd
}
// SetWorkingDir sets the working directory
func (s *Shell) SetWorkingDir(dir string) error {
s.mu.Lock()
defer s.mu.Unlock()
// Verify the directory exists
if _, err := os.Stat(dir); err != nil {
return fmt.Errorf("directory does not exist: %w", err)
}
s.cwd = dir
return nil
}
// GetEnv returns a copy of the environment variables
func (s *Shell) GetEnv() []string {
s.mu.Lock()
defer s.mu.Unlock()
env := make([]string, len(s.env))
copy(env, s.env)
return env
}
// SetEnv sets an environment variable
func (s *Shell) SetEnv(key, value string) {View on GitHub (pinned to 7944b8e522)
Solutions
- Create the directory first (os.MkdirAll) before calling SetWorkingDir.
- Verify the path is a directory, not a file, and fix the caller.
- Check permissions on the path and its parents.
- Re-check the stored path for staleness (deleted temp/worktree dirs) and resolve to an existing directory.
Example fix
// before
shell.SetWorkingDir("/tmp/build-123") // may not exist
// after
os.MkdirAll("/tmp/build-123", 0o755)
shell.SetWorkingDir("/tmp/build-123") Defensive patterns
Strategy: validation
Validate before calling
func dirExists(p string) bool {
info, err := os.Stat(p)
return err == nil && info.IsDir()
}
if !dirExists(dir) { os.MkdirAll(dir, 0o755) }
err := sh.SetWorkingDir(dir) Try / catch
if err := sh.SetWorkingDir(dir); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {
os.MkdirAll(dir, 0o755)
err = sh.SetWorkingDir(dir)
}
} Prevention
- Always os.MkdirAll the target before SetWorkingDir.
- Check info.IsDir() to catch file-instead-of-directory mistakes.
- Validate persisted cwd paths when restoring sessions — they may be stale.
- Use absolute paths to avoid dependency on the process cwd.
When it happens
Trigger: Calling SetWorkingDir("/path/that/does/not/exist"), calling it with a file path instead of a directory, or with a path the process lacks search permission on. Any os.Stat error (including permission) yields this message.
Common situations: Restoring a session whose previous cwd was deleted; pointing the shell at a worktree or temp dir that was cleaned up; typo in path; using a path inside a container that was never mounted.
Related errors
- prompt is required
- session id missing from context
- agent message id missing from context
- invalid client_id
- not a valid bedrock api key
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/63b413efe98671c1.
Report an issue: GitHub.